forked from p15670423/monkey
Merge pull request #1887 from guardicore/agent-refactor
This commit is contained in:
commit
16e887a94a
|
@ -1,4 +1,4 @@
|
|||
monkey/tests/data_for_tests/ransomware_targets/** -text
|
||||
monkey/tests/data_for_tests/test_readme.txt -text
|
||||
monkey/tests/data_for_tests/stable_file.txt -text
|
||||
monkey/infection_monkey/ransomware/ransomware_readme.txt -text
|
||||
monkey/infection_monkey/payload/ransomware/ransomware_readme.txt -text
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
default_stages: [commit]
|
||||
repos:
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.8.0
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
|
@ -12,16 +12,16 @@ repos:
|
|||
name: isort (pyi)
|
||||
types: [pyi]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1
|
||||
rev: 22.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.9.1
|
||||
rev: 4.0.1
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: [dlint]
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
rev: v4.1.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
|
@ -31,7 +31,7 @@ repos:
|
|||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/eslint/eslint
|
||||
rev: v7.24.0
|
||||
rev: v8.12.0
|
||||
hooks:
|
||||
- id: eslint
|
||||
args: ["monkey/monkey_island/cc/ui/src/", "--fix", "--max-warnings=0"]
|
||||
|
@ -45,7 +45,7 @@ repos:
|
|||
exclude: "monkey/monkey_island/cc/ui"
|
||||
stages: [push]
|
||||
- repo: https://github.com/swimmio/pre-commit
|
||||
rev: v0.2
|
||||
rev: v0.7
|
||||
hooks:
|
||||
- id: swimm-verify
|
||||
- repo: https://github.com/jendrikseipp/vulture
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
{
|
||||
"id": "AzD8XysWg1BBXCjCDkfq",
|
||||
"name": "Add a new configuration setting to the Agent ⚙",
|
||||
"task": {
|
||||
"dod": "Make the max victim number that Monkey will find before stopping configurable by the user instead of constant.",
|
||||
"tests": [],
|
||||
"hints": [
|
||||
"Look for `victims_max_exploit` - it's rather similar."
|
||||
]
|
||||
},
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "# Make something configurable\n\nIn this unit, you will learn how to add a configuration option to Monkey and how to use it in the Monkey Agent code. \n\n![computer fire](https://media.giphy.com/media/7J4P7cUur2DlErijp3/giphy.gif \"computer fire\")\n\n## Why is this important?\n\nEnabling users to configure the Monkey's behaviour gives them a lot more freedom in how they want to use the Monkey and enables more use cases.\n\n## What is \"Max victims to find\"?\n\nThe Monkey has a function which finds \"victim\" machines on the network for the Monkey to try and exploit. It's called `get_victim_machines`. This function accepts an argument which limits how many machines the Monkey should find.\n\nWe want to make that value editable by the user instead of constant in the code.\n\n## Manual testing\n\n1. After you've performed the required changes, reload the Server and check your value exists in the Internal tab of the config (see image).\n\n![](https://i.imgur.com/e0XAxuV.png)\n\n2. Set the new value to 1, and run Monkey locally (from source). See that the Monkey only scans one machine."
|
||||
},
|
||||
{
|
||||
"type": "snippet",
|
||||
"path": "monkey/infection_monkey/config.py",
|
||||
"comments": [],
|
||||
"firstLineNumber": 103,
|
||||
"lines": [
|
||||
" exploiter_classes = []",
|
||||
" system_info_collector_classes = []",
|
||||
" ",
|
||||
"* # how many victims to look for in a single scan iteration",
|
||||
"* victims_max_find = 100",
|
||||
" ",
|
||||
" # how many victims to exploit before stopping",
|
||||
" victims_max_exploit = 100"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "snippet",
|
||||
"path": "monkey/infection_monkey/monkey.py",
|
||||
"comments": [],
|
||||
"firstLineNumber": 220,
|
||||
"lines": [
|
||||
" if not WormConfiguration.alive:",
|
||||
" logger.info(\"Marked not alive from configuration\")",
|
||||
" ",
|
||||
"* machines = self._network.get_victim_machines(",
|
||||
"* max_find=WormConfiguration.victims_max_find,",
|
||||
"* stop_callback=ControlClient.check_for_stop,",
|
||||
"* )",
|
||||
" for machine in machines:",
|
||||
" if ControlClient.check_for_stop():",
|
||||
" break"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "snippet",
|
||||
"path": "monkey/monkey_island/cc/services/config_schema/internal.py",
|
||||
"comments": [],
|
||||
"firstLineNumber": 28,
|
||||
"lines": [
|
||||
" \"title\": \"Monkey\",",
|
||||
" \"type\": \"object\",",
|
||||
" \"properties\": {",
|
||||
"* \"victims_max_find\": {",
|
||||
"* \"title\": \"Max victims to find\",",
|
||||
"* \"type\": \"integer\",",
|
||||
"* \"default\": 100,",
|
||||
"* \"description\": \"Determines the maximum number of machines the monkey is \"",
|
||||
"* \"allowed to scan\",",
|
||||
"* },",
|
||||
" \"victims_max_exploit\": {",
|
||||
" \"title\": \"Max victims to exploit\",",
|
||||
" \"type\": \"integer\","
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"text": "* When changing config schema by adding or deleting keys, you need to update the Blackbox Test configurations as well [here](https://github.com/guardicore/monkey/tree/develop/envs/monkey_zoo/blackbox/config_templates)."
|
||||
}
|
||||
],
|
||||
"symbols": {},
|
||||
"file_version": "2.0.3",
|
||||
"meta": {
|
||||
"app_version": "0.6.6-2",
|
||||
"file_blobs": {
|
||||
"monkey/infection_monkey/config.py": "8f4984ba6563564343282765ab498efca5d89ba8",
|
||||
"monkey/infection_monkey/monkey.py": "4160a36e0e624404d77526472d51dd07bba49e5a",
|
||||
"monkey/monkey_island/cc/services/config_schema/internal.py": "86318eaf19b9991a8af5de861a3eb085238e17a4"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,23 +18,24 @@
|
|||
"type": "snippet",
|
||||
"path": "monkey/infection_monkey/post_breach/actions/schedule_jobs.py",
|
||||
"comments": [],
|
||||
"firstLineNumber": 12,
|
||||
"firstLineNumber": 15,
|
||||
"lines": [
|
||||
" \"\"\"",
|
||||
" ",
|
||||
" def __init__(self):",
|
||||
" def __init__(self, telemetry_messenger: ITelemetryMessenger):",
|
||||
"* linux_cmds, windows_cmds = get_commands_to_schedule_jobs()",
|
||||
"+ pass",
|
||||
"*",
|
||||
"+ # Swimmer: IMPLEMENT HERE!",
|
||||
"* super(ScheduleJobs, self).__init__(",
|
||||
"* telemetry_messenger,",
|
||||
"* name=POST_BREACH_JOB_SCHEDULING,",
|
||||
"* linux_cmd=\" \".join(linux_cmds),",
|
||||
"* windows_cmd=windows_cmds,",
|
||||
"* )",
|
||||
"*",
|
||||
"* def run(self):",
|
||||
"* super(ScheduleJobs, self).run()",
|
||||
"* def run(self, options: Dict):",
|
||||
"* super(ScheduleJobs, self).run(options)",
|
||||
"* remove_scheduled_jobs()"
|
||||
]
|
||||
},
|
||||
|
@ -44,11 +45,11 @@
|
|||
}
|
||||
],
|
||||
"symbols": {},
|
||||
"file_version": "2.0.1",
|
||||
"file_version": "2.0.3",
|
||||
"meta": {
|
||||
"app_version": "0.4.1-1",
|
||||
"app_version": "0.6.6-2",
|
||||
"file_blobs": {
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py": "e7845968a0c27d2eba71a8889645fe88491cb2a8"
|
||||
"monkey/infection_monkey/post_breach/actions/schedule_jobs.py": "4ab023e35fa4424f0c6583233f5b056c7b1cad51"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,15 +34,18 @@
|
|||
"lines": [
|
||||
" ",
|
||||
" class AccountDiscovery(PBA):",
|
||||
" def __init__(self):",
|
||||
" def __init__(self, telemetry_messenger: ITelemetryMessenger):",
|
||||
"* linux_cmds, windows_cmds = get_commands_to_discover_accounts()",
|
||||
"+ # SWIMMER: Implement here!",
|
||||
"* super().__init__(",
|
||||
"+ pass",
|
||||
"* POST_BREACH_ACCOUNT_DISCOVERY, linux_cmd=\" \".join(linux_cmds), windows_cmd=windows_cmds",
|
||||
"* telemetry_messenger,",
|
||||
"* POST_BREACH_ACCOUNT_DISCOVERY,",
|
||||
"* linux_cmd=\" \".join(linux_cmds),",
|
||||
"* windows_cmd=windows_cmds,",
|
||||
"* )"
|
||||
],
|
||||
"firstLineNumber": 7,
|
||||
"firstLineNumber": 8,
|
||||
"path": "monkey/infection_monkey/post_breach/actions/discover_accounts.py",
|
||||
"comments": []
|
||||
},
|
||||
|
@ -65,7 +68,7 @@
|
|||
" \"type\": \"string\",",
|
||||
" \"enum\": [\"ClearCommandHistory\"],"
|
||||
],
|
||||
"firstLineNumber": 80,
|
||||
"firstLineNumber": 78,
|
||||
"path": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
||||
"comments": []
|
||||
},
|
||||
|
@ -77,11 +80,11 @@
|
|||
"symbols": {},
|
||||
"file_version": "2.0.3",
|
||||
"meta": {
|
||||
"app_version": "0.5.7-0",
|
||||
"app_version": "0.6.6-2",
|
||||
"file_blobs": {
|
||||
"monkey/common/common_consts/post_breach_consts.py": "01d31448269e5581dbe0176c289f7dd36cc5854f",
|
||||
"monkey/infection_monkey/post_breach/actions/discover_accounts.py": "8fdebd0df97655e4cba3aebcdcf3c5ed1d1b6cbd",
|
||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "88a3e8cb59fb0d1c07c9487bcb4eaab7b8087d84"
|
||||
"monkey/common/common_consts/post_breach_consts.py": "19b6c4f19b7223f115976a0050ca04ab97e52f8e",
|
||||
"monkey/infection_monkey/post_breach/actions/discover_accounts.py": "a153cf5b6185c9771414fc5ae49d441efc7294b6",
|
||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "d6831ed63b17f327d719a05840d7e51202fa5ccb"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
.travis.yml
15
.travis.yml
|
@ -7,10 +7,11 @@ group: travis_latest
|
|||
language: python
|
||||
|
||||
env:
|
||||
- PIP_CACHE_DIR=$HOME/.cache/pip PIPENV_CACHE_DIR=$HOME/.cache/pipenv
|
||||
- PIP_CACHE_DIR=$HOME/.cache/pip PIPENV_CACHE_DIR=$HOME/.cache/pipenv LIBSODIUM_MAKE_ARGS=-j8
|
||||
|
||||
cache:
|
||||
- pip
|
||||
- pip: true
|
||||
- npm: true
|
||||
- directories:
|
||||
- "$HOME/.npm"
|
||||
- $PIP_CACHE_DIR
|
||||
|
@ -20,10 +21,13 @@ python:
|
|||
- 3.7
|
||||
|
||||
os: linux
|
||||
vm:
|
||||
size: x-large
|
||||
|
||||
|
||||
install:
|
||||
# Python
|
||||
- nproc
|
||||
- pip install pipenv --upgrade
|
||||
# Install island and monkey requirements as they are needed by UT's
|
||||
- pushd monkey/monkey_island
|
||||
|
@ -37,7 +41,7 @@ install:
|
|||
- node --version
|
||||
- npm --version
|
||||
- nvm --version
|
||||
- nvm install 12
|
||||
- nvm install 16
|
||||
- nvm use node
|
||||
- npm i -g eslint
|
||||
- node --version
|
||||
|
@ -65,7 +69,8 @@ script:
|
|||
|
||||
## Run unit tests and generate coverage data
|
||||
- cd monkey # This is our source dir
|
||||
- python -m pytest --cov=. # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path.
|
||||
- pip install pytest-xdist
|
||||
- python -m pytest -n auto --cov=. # Have to use `python -m pytest` instead of `pytest` to add "{$builddir}/monkey/monkey" to sys.path.
|
||||
|
||||
# Check JS code. The npm install must happen AFTER the flake8 because the node_modules folder will cause a lot of errors.
|
||||
- cd monkey_island/cc/ui
|
||||
|
@ -80,7 +85,7 @@ script:
|
|||
|
||||
# verify swimm
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- curl -L https://github.com/swimmio/SwimmReleases/releases/latest/download/packed-swimm-linux-cli --output swimm-cli
|
||||
- curl -L https://releases.swimm.io/ci/latest/packed-swimm-linux-cli --output swimm-cli
|
||||
- chmod u+x swimm-cli
|
||||
- ./swimm-cli --version
|
||||
- ./swimm-cli verify
|
||||
|
|
38
CHANGELOG.md
38
CHANGELOG.md
|
@ -8,16 +8,27 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
## [Unreleased]
|
||||
### Added
|
||||
- credentials.json file for storing Monkey Island user login information. #1206
|
||||
- "GET /api/propagation-credentials/<string:guid>" endpoint for agents to
|
||||
retrieve updated credentials from the Island. #1538
|
||||
- SSHCollector as a configurable System info Collector. #1606
|
||||
- deployment_scrips/install-infection-monkey-service.sh to install an AppImage
|
||||
as a service. #1552
|
||||
- The ability to download the Monkey Island logs from the Infection Map page. #1640
|
||||
|
||||
### Changed
|
||||
- "Communicate as Backdoor User" PBA's HTTP requests to request headers only and
|
||||
include a timeout. #1577
|
||||
- The setup procedure for custom server_config.json files to be simpler. #1576
|
||||
- The order and content of Monkey Island's initialization logging to give
|
||||
clearer instructions to the user and avoid confusion. #1684
|
||||
- The process list collection system info collector to now be a post-breach action. #1697
|
||||
- The "/api/monkey/download" endpoint to accept an OS and return a file. #1675
|
||||
- Log messages to contain human-readable thread names. #1766
|
||||
- The log file name to `infection-monkey-agent-<TIMESTAMP>-<RANDOM_STRING>.log`. #1761
|
||||
- "Logs" page renamed to "Telemetries". #1640
|
||||
|
||||
### Removed
|
||||
- The VSFTPD exploiter. #1533
|
||||
- VSFTPD exploiter. #1533
|
||||
- Manual agent run command for CMD. #1570
|
||||
- Sambacry exploiter. #1567, #1693
|
||||
- "Kill file" option in the config. #1536
|
||||
|
@ -34,6 +45,23 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Hostname system info collector. #1535
|
||||
- Max iterations and timeout between iterations config options. #1600
|
||||
- MITRE ATT&CK configuration screen. #1532
|
||||
- Propagation credentials from "GET /api/monkey/<string:guid>" endpoint. #1538
|
||||
- "GET /api/monkey_control/check_remote_port/<string:port>" endpoint. #1635
|
||||
- Max victims to find/exploit, TCP scan interval and TCP scan get banner internal options. #1597
|
||||
- MySQL fingerprinter. #1648
|
||||
- MS08-067 (Conficker) exploiter. #1677
|
||||
- Agent bootloader. #1676
|
||||
- Zero Trust integration with ScoutSuite. #1669
|
||||
- ShellShock exploiter. #1733
|
||||
- ElasticGroovy exploiter. #1732
|
||||
- T1082 attack technique report. #1754
|
||||
- 32-bit agents. #1675
|
||||
- Log path config options. #1761
|
||||
- "smb_service_name" option. #1741
|
||||
- Struts2 exploiter. #1869
|
||||
- Drupal exploiter. #1869
|
||||
- WebLogic exploiter. #1869
|
||||
- The /api/t1216-pba/download endpoint. #1864
|
||||
- Island log download button from "Telemetries"(previously called "Logs") page. #1640
|
||||
|
||||
### Fixed
|
||||
|
@ -41,9 +69,14 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Windows "run as a user" powershell command for manual agent runs. #1570
|
||||
- A bug in the "Signed Script Proxy Execution" PBA that downloaded the exe on Linux
|
||||
systems as well. #1557
|
||||
- A bug where T1216_random_executable.exe was copied to disk even if the signed
|
||||
script proxy execution PBA was disabled. #1864
|
||||
|
||||
|
||||
### Security
|
||||
|
||||
- Change SSH exploiter so that it does not set the permissions of the agent
|
||||
binary in /tmp on the target system to 777, as this could allow a malicious
|
||||
actor with local access to escalate their privileges. #1750
|
||||
|
||||
## [1.13.0] - 2022-01-25
|
||||
### Added
|
||||
|
@ -54,6 +87,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Exploiters attempting to start servers listening on privileged ports,
|
||||
resulting in failed propagation. 8f53a5c
|
||||
|
||||
|
||||
## [1.12.0] - 2021-10-27
|
||||
### Added
|
||||
- A new exploiter that allows propagation via PowerShell Remoting. #1246
|
||||
|
|
|
@ -58,10 +58,8 @@ The Infection Monkey uses the following techniques and exploits to propagate to
|
|||
* SSH
|
||||
* SMB
|
||||
* WMI
|
||||
* Shellshock
|
||||
* Conficker
|
||||
* Elastic Search (CVE-2015-1427)
|
||||
* Weblogic server
|
||||
* Log4Shell
|
||||
* Zerologon
|
||||
* and more, see our [Documentation hub](https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/) for more information about our RCE exploiters.
|
||||
|
||||
## Setup
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
LINUXDEPLOY_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
PYTHON_VERSION="3.7.12"
|
||||
PYTHON_VERSION="3.7.13"
|
||||
PYTHON_APPIMAGE_URL="https://github.com/niess/python-appimage/releases/download/python3.7/python${PYTHON_VERSION}-cp37-cp37m-manylinux1_x86_64.AppImage"
|
||||
APPIMAGE_DIR="$(realpath $(dirname $BASH_SOURCE[0]))"
|
||||
APPDIR="$APPIMAGE_DIR/squashfs-root"
|
||||
|
@ -28,6 +28,7 @@ setup_build_dir() {
|
|||
local agent_binary_dir=$1
|
||||
local monkey_repo=$2
|
||||
local deployment_type=$3
|
||||
local is_release_build=$4
|
||||
|
||||
pushd $APPIMAGE_DIR
|
||||
|
||||
|
@ -44,7 +45,7 @@ setup_build_dir() {
|
|||
install_mongodb
|
||||
|
||||
generate_ssl_cert "$BUILD_DIR"
|
||||
build_frontend "$BUILD_DIR"
|
||||
build_frontend "$BUILD_DIR" "$is_release_build"
|
||||
|
||||
remove_python_appdir_artifacts
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
WORKSPACE=${WORKSPACE:-$HOME}
|
||||
DEFAULT_REPO_MONKEY_HOME=$WORKSPACE/git/monkey
|
||||
MONKEY_ORIGIN_URL="https://github.com/guardicore/monkey.git"
|
||||
NODE_SRC=https://deb.nodesource.com/setup_12.x
|
||||
NODE_SRC=https://deb.nodesource.com/setup_16.x
|
||||
BUILD_SCRIPTS_DIR="$(realpath $(dirname $BASH_SOURCE[0]))"
|
||||
DIST_DIR="$BUILD_SCRIPTS_DIR/dist"
|
||||
|
||||
|
@ -196,8 +196,13 @@ fi
|
|||
install_build_prereqs
|
||||
install_package_specific_build_prereqs "$WORKSPACE"
|
||||
|
||||
is_release_build=false
|
||||
# Monkey version is empty on release build
|
||||
if [ ! -z "$monkey_version" ]; then
|
||||
is_release_build=true
|
||||
fi
|
||||
|
||||
setup_build_dir "$agent_binary_dir" "$monkey_repo" "$deployment_type"
|
||||
setup_build_dir "$agent_binary_dir" "$monkey_repo" "$deployment_type" "$is_release_build"
|
||||
commit_id=$(get_commit_id "$monkey_repo")
|
||||
build_package "$monkey_version" "$commit_id" "$DIST_DIR"
|
||||
|
||||
|
|
|
@ -42,9 +42,7 @@ download_monkey_agent_binaries() {
|
|||
load_monkey_binary_config
|
||||
|
||||
mkdir -p "${island_binaries_path}" || handle_error
|
||||
curl -L -o "${island_binaries_path}/${LINUX_32_BINARY_NAME}" "${LINUX_32_BINARY_URL}"
|
||||
curl -L -o "${island_binaries_path}/${LINUX_64_BINARY_NAME}" "${LINUX_64_BINARY_URL}"
|
||||
curl -L -o "${island_binaries_path}/${WINDOWS_32_BINARY_NAME}" "${WINDOWS_32_BINARY_URL}"
|
||||
curl -L -o "${island_binaries_path}/${WINDOWS_64_BINARY_NAME}" "${WINDOWS_64_BINARY_URL}"
|
||||
}
|
||||
|
||||
|
@ -76,11 +74,18 @@ generate_ssl_cert() {
|
|||
|
||||
build_frontend() {
|
||||
local ui_dir="$1/monkey_island/cc/ui"
|
||||
local is_release_build=$2
|
||||
pushd "$ui_dir" || handle_error
|
||||
|
||||
log_message "Generating front end"
|
||||
npm ci
|
||||
npm run dist
|
||||
if [ "$is_release_build" == true ]; then
|
||||
log_message "Running production front end build"
|
||||
npm run dist
|
||||
else
|
||||
log_message "Running development front end build"
|
||||
npm run dev
|
||||
fi
|
||||
|
||||
popd || handle_error
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ install_package_specific_build_prereqs() {
|
|||
setup_build_dir() {
|
||||
local agent_binary_dir=$1
|
||||
local monkey_repo=$2
|
||||
local is_release_build=$4
|
||||
local build_dir=$DOCKER_DIR/monkey
|
||||
|
||||
mkdir "$build_dir"
|
||||
|
@ -22,7 +23,7 @@ setup_build_dir() {
|
|||
|
||||
generate_ssl_cert "$build_dir"
|
||||
|
||||
build_frontend "$build_dir"
|
||||
build_frontend "$build_dir" "$is_release_build"
|
||||
}
|
||||
|
||||
copy_entrypoint_to_build_dir() {
|
||||
|
|
|
@ -22,7 +22,7 @@ The first argument is an empty directory (script can create one). The second arg
|
|||
|
||||
- `.\deploy_windows.ps1` (Sets up monkey in current directory under .\infection_monkey)
|
||||
- `.\deploy_windows.ps1 -monkey_home "C:\test"` (Sets up monkey in C:\test)
|
||||
- `.\deploy_windows.ps1 -branch "master"` (Sets up master branch instead of develop in current dir)
|
||||
- `.\deploy_windows.ps1 -branch 'master'` (Sets up master branch instead of develop in current dir)
|
||||
|
||||
You may also pass in an optional `agents=$false` parameter to disable downloading the latest agent binaries.
|
||||
|
||||
|
|
|
@ -25,15 +25,9 @@ get_latest_release() {
|
|||
MONKEY_LATEST_RELEASE=$(get_latest_release "guardicore/monkey")
|
||||
|
||||
# Monkey binaries
|
||||
export LINUX_32_BINARY_NAME="monkey-linux-32"
|
||||
export LINUX_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-32"
|
||||
|
||||
export LINUX_64_BINARY_NAME="monkey-linux-64"
|
||||
export LINUX_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-linux-64"
|
||||
|
||||
export WINDOWS_32_BINARY_NAME="monkey-windows-32.exe"
|
||||
export WINDOWS_32_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-32.exe"
|
||||
|
||||
export WINDOWS_64_BINARY_NAME="monkey-windows-64.exe"
|
||||
export WINDOWS_64_BINARY_URL="https://github.com/guardicore/monkey/releases/download/$MONKEY_LATEST_RELEASE/monkey-windows-64.exe"
|
||||
|
||||
|
|
|
@ -12,12 +12,8 @@ $PYTHON_URL = "https://www.python.org/ftp/python/3.7.7/python-3.7.7-amd64.exe"
|
|||
|
||||
|
||||
# Monkey binaries
|
||||
$LINUX_32_BINARY_URL = $MONKEY_DOWNLOAD_URL + "monkey-linux-32"
|
||||
$LINUX_32_BINARY_PATH = "monkey-linux-32"
|
||||
$LINUX_64_BINARY_URL = $MONKEY_DOWNLOAD_URL + "monkey-linux-64"
|
||||
$LINUX_64_BINARY_PATH = "monkey-linux-64"
|
||||
$WINDOWS_32_BINARY_URL = $MONKEY_DOWNLOAD_URL + "monkey-windows-32.exe"
|
||||
$WINDOWS_32_BINARY_PATH = "monkey-windows-32.exe"
|
||||
$WINDOWS_64_BINARY_URL = $MONKEY_DOWNLOAD_URL + "monkey-windows-64.exe"
|
||||
$WINDOWS_64_BINARY_PATH = "monkey-windows-64.exe"
|
||||
|
||||
|
@ -36,6 +32,6 @@ $UPX_FOLDER = "upx-3.96-win64"
|
|||
$MONGODB_URL = "https://downloads.mongodb.org/win32/mongodb-win32-x86_64-2012plus-v4.2-latest.zip"
|
||||
$OPEN_SSL_URL = "https://indy.fulgan.com/SSL/openssl-1.0.2u-x64_86-win64.zip"
|
||||
$CPP_URL = "https://go.microsoft.com/fwlink/?LinkId=746572"
|
||||
$NPM_URL = "https://nodejs.org/dist/v12.14.1/node-v12.14.1-x64.msi"
|
||||
$NPM_URL = "https://nodejs.org/dist/v16.14.2/node-v16.14.2-x64.msi"
|
||||
$UPX_URL = "https://github.com/upx/upx/releases/download/v3.96/upx-3.96-win64.zip"
|
||||
$SWIMM_URL="https://github.com/swimmio/SwimmReleases/releases/download/v0.4.4-0/Swimm-Setup-0.4.4-0.exe"
|
||||
|
|
|
@ -93,7 +93,7 @@ log_message "Cloning files from git"
|
|||
branch=${2:-"develop"}
|
||||
log_message "Branch selected: ${branch}"
|
||||
if [[ ! -d "$monkey_home/monkey" ]]; then # If not already cloned
|
||||
git clone --single-branch --recurse-submodules -b "$branch" "${MONKEY_GIT_URL}" "${monkey_home}" 2>&1 || handle_error
|
||||
git clone --recurse-submodules -b "$branch" "${MONKEY_GIT_URL}" "${monkey_home}" 2>&1 || handle_error
|
||||
fi
|
||||
|
||||
# Create folders
|
||||
|
@ -161,20 +161,15 @@ agents=${3:-true}
|
|||
if [ "$agents" = true ] ; then
|
||||
log_message "Downloading binaries"
|
||||
if exists wget; then
|
||||
wget -c -N -P ${ISLAND_BINARIES_PATH} ${LINUX_32_BINARY_URL}
|
||||
wget -c -N -P ${ISLAND_BINARIES_PATH} ${LINUX_64_BINARY_URL}
|
||||
wget -c -N -P ${ISLAND_BINARIES_PATH} ${WINDOWS_32_BINARY_URL}
|
||||
wget -c -N -P ${ISLAND_BINARIES_PATH} ${WINDOWS_64_BINARY_URL}
|
||||
else
|
||||
curl -o ${ISLAND_BINARIES_PATH}\monkey-linux-32 ${LINUX_32_BINARY_URL}
|
||||
curl -o ${ISLAND_BINARIES_PATH}\monkey-linux-64 ${LINUX_64_BINARY_URL}
|
||||
curl -o ${ISLAND_BINARIES_PATH}\monkey-windows-32.exe ${WINDOWS_32_BINARY_URL}
|
||||
curl -o ${ISLAND_BINARIES_PATH}\monkey-windows-64.exe ${WINDOWS_64_BINARY_URL}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Allow them to be executed
|
||||
chmod a+x "$ISLAND_BINARIES_PATH/$LINUX_32_BINARY_NAME"
|
||||
chmod a+x "$ISLAND_BINARIES_PATH/$LINUX_64_BINARY_NAME"
|
||||
|
||||
# If a user haven't installed mongo manually check if we can install it with our script
|
||||
|
@ -197,7 +192,7 @@ chmod u+x "${ISLAND_PATH}"/linux/create_certificate.sh
|
|||
# Update node
|
||||
if ! exists npm; then
|
||||
log_message "Installing nodejs"
|
||||
node_src=https://deb.nodesource.com/setup_12.x
|
||||
node_src=https://deb.nodesource.com/setup_16.x
|
||||
if exists curl; then
|
||||
curl -sL $node_src | sudo -E bash -
|
||||
else
|
||||
|
@ -207,8 +202,7 @@ if ! exists npm; then
|
|||
fi
|
||||
|
||||
pushd "$ISLAND_PATH/cc/ui" || handle_error
|
||||
npm install sass-loader node-sass webpack --save-dev
|
||||
npm update
|
||||
npm ci
|
||||
|
||||
log_message "Generating front end"
|
||||
npm run dist
|
||||
|
|
|
@ -209,9 +209,7 @@ function Deploy-Windows([String] $monkey_home = (Get-Item -Path ".\").FullName,
|
|||
"Adding binaries"
|
||||
$binaries = (Join-Path -Path $monkey_home -ChildPath $MONKEY_ISLAND_DIR | Join-Path -ChildPath "\cc\binaries")
|
||||
New-Item -ItemType directory -path $binaries -ErrorAction SilentlyContinue
|
||||
$webClient.DownloadFile($LINUX_32_BINARY_URL, (Join-Path -Path $binaries -ChildPath $LINUX_32_BINARY_PATH))
|
||||
$webClient.DownloadFile($LINUX_64_BINARY_URL, (Join-Path -Path $binaries -ChildPath $LINUX_64_BINARY_PATH))
|
||||
$webClient.DownloadFile($WINDOWS_32_BINARY_URL, (Join-Path -Path $binaries -ChildPath $WINDOWS_32_BINARY_PATH))
|
||||
$webClient.DownloadFile($WINDOWS_64_BINARY_URL, (Join-Path -Path $binaries -ChildPath $WINDOWS_64_BINARY_PATH))
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
|
||||
SYSTEMD_UNIT_FILENAME="infection-monkey.service"
|
||||
SYSTEMD_DIR="/lib/systemd/system"
|
||||
MONKEY_BIN="/opt/infection-monkey/bin"
|
||||
APPIMAGE_NAME="InfectionMonkey.AppImage"
|
||||
|
||||
echo_help() {
|
||||
echo "Installs the Infection Monkey service to run on boot."
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " install-infection-monkey-service.sh --user <USERNAME> --appimage <PATH>"
|
||||
echo " install-infection-monkey-service.sh --uninstall"
|
||||
echo " install-infection-monkey-service.sh -h|--help"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --user User to run the service as"
|
||||
echo " --appimage Path to AppImage"
|
||||
echo " --uninstall Uninstall the Infection Monkey service"
|
||||
}
|
||||
|
||||
install_service() {
|
||||
move_appimage "$2"
|
||||
|
||||
cat > "${SCRIPT_DIR}/${SYSTEMD_UNIT_FILENAME}" << EOF
|
||||
[Unit]
|
||||
Description=Infection Monkey Runner
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=$1
|
||||
Type=simple
|
||||
ExecStart="${MONKEY_BIN}/${APPIMAGE_NAME}"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
umask 077
|
||||
sudo mv "${SCRIPT_DIR}/${SYSTEMD_UNIT_FILENAME}" "${SYSTEMD_DIR}/${SYSTEMD_UNIT_FILENAME}"
|
||||
sudo systemctl enable "${SYSTEMD_UNIT_FILENAME}" &>/dev/null
|
||||
|
||||
echo -e "The Infection Monkey service has been installed and will start on boot.\n\
|
||||
Run 'systemctl start infection-monkey' to start the service now."
|
||||
}
|
||||
|
||||
uninstall_service() {
|
||||
if [ -f "${MONKEY_BIN}/${APPIMAGE_NAME}" ] ; then
|
||||
sudo rm -f "${MONKEY_BIN}/${APPIMAGE_NAME}"
|
||||
fi
|
||||
|
||||
if [ -f "${SYSTEMD_DIR}/${SYSTEMD_UNIT_FILENAME}" ] ; then
|
||||
sudo systemctl stop "${SYSTEMD_UNIT_FILENAME}" 2>/dev/null
|
||||
sudo systemctl disable "${SYSTEMD_UNIT_FILENAME}" &>/dev/null
|
||||
sudo rm "${SYSTEMD_DIR}/${SYSTEMD_UNIT_FILENAME}"
|
||||
sudo systemctl daemon-reload
|
||||
fi
|
||||
|
||||
echo "The Infection Monkey service has been uninstalled"
|
||||
}
|
||||
|
||||
move_appimage() {
|
||||
sudo mkdir --mode=0755 -p "${MONKEY_BIN}"
|
||||
|
||||
if [ "$1" != "${MONKEY_BIN}/${APPIMAGE_NAME}" ] ; then
|
||||
umask 022
|
||||
sudo cp "$appimage_path" "${MONKEY_BIN}/${APPIMAGE_NAME}"
|
||||
sudo chmod 755 "${MONKEY_BIN}/${APPIMAGE_NAME}"
|
||||
fi
|
||||
}
|
||||
|
||||
user_exists() {
|
||||
id -u "$1" &>/dev/null
|
||||
}
|
||||
|
||||
assert_parameter_supplied() {
|
||||
if [ -z "$2" ] ; then
|
||||
echo "Error: missing required parameter '$1'"
|
||||
echo_help
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
has_sudo() {
|
||||
# 0 true, 1 false
|
||||
sudo -nv > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
exit_if_missing_argument() {
|
||||
if [ -z "$2" ] || [ "${2:0:1}" == "-" ]; then
|
||||
echo "Error: Argument for parameter '$1' is missing" >&2
|
||||
echo_help
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_uninstall=false
|
||||
uname=""
|
||||
appimage_path=""
|
||||
|
||||
while (( "$#" )); do
|
||||
case "$1" in
|
||||
--user)
|
||||
exit_if_missing_argument "$1" "$2"
|
||||
|
||||
uname=$2
|
||||
shift 2
|
||||
;;
|
||||
--appimage)
|
||||
exit_if_missing_argument "$1" "$2"
|
||||
|
||||
appimage_path=$2
|
||||
shift 2
|
||||
;;
|
||||
--uninstall)
|
||||
do_uninstall=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unsupported parameter $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! has_sudo; then
|
||||
echo "Error: You need root permissions for some of this script operations. \
|
||||
Run \`sudo -v\`, enter your password, and then re-run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if $do_uninstall ; then
|
||||
uninstall_service
|
||||
exit 0
|
||||
fi
|
||||
|
||||
assert_parameter_supplied "--user" "$uname"
|
||||
assert_parameter_supplied "--appimage" "$appimage_path"
|
||||
|
||||
if ! user_exists "$uname" ; then
|
||||
echo "Error: User '$uname' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$appimage_path" ] ; then
|
||||
if [ ! -f "${SCRIPT_DIR}/$appimage_path" ] ; then
|
||||
echo "Error: AppImage '$appimage_path' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
appimage_path="${SCRIPT_DIR}/$appimage_path"
|
||||
fi
|
||||
|
||||
install_service "$uname" "$appimage_path"
|
|
@ -11,6 +11,7 @@ Below are some of the most common questions we receive about the Infection Monke
|
|||
- [I updated to a new version of the Infection Monkey and I'm being asked to delete my existing data directory. Why?](#i-updated-to-a-new-version-of-the-infection-monkey-and-im-being-asked-to-delete-my-existing-data-directory-why)
|
||||
- [How can I use an old data directory?](#how-can-i-use-an-old-data-directory)
|
||||
- [How long does a single Infection Monkey agent run? Is there a time limit?](#how-long-does-a-single-infection-monkey-agent-run-is-there-a-time-limit)
|
||||
- [How long does it take to stop all running Infection Monkey agents?](#how-long-does-it-take-to-stop-all-running-infection-monkey-agents)
|
||||
- [Is the Infection Monkey a malware/virus?](#is-the-infection-monkey-a-malwarevirus)
|
||||
- [Reset the Monkey Island password](#reset-the-monkey-island-password)
|
||||
- [Should I run the Infection Monkey continuously?](#should-i-run-the-infection-monkey-continuously)
|
||||
|
@ -59,6 +60,12 @@ ref "/reference/data_directory" >}}).
|
|||
|
||||
The Infection Monkey agent shuts off either when it can't find new victims or it has exceeded the quota of victims as defined in the configuration.
|
||||
|
||||
## How long does it take to stop all running Infection Monkey agents?
|
||||
|
||||
On the Infection Map page, when <b>Kill All Monkeys</b> is pressed, the agents
|
||||
try to finish execution safely. This can take up to 2 minutes, but will be much
|
||||
shorter on average.
|
||||
|
||||
## Is the Infection Monkey a malware/virus?
|
||||
|
||||
The Infection Monkey is not malware, but it uses similar techniques to safely
|
||||
|
@ -189,10 +196,20 @@ It's also possible to change the default log level by editing `log_level` value
|
|||
|
||||
#### Infection Monkey agent logs
|
||||
|
||||
The Infection Monkey agent log file can be found in the following paths on machines where it was executed:
|
||||
The Infection Monkey agent log file can be found in directories specified for
|
||||
temporary files on the machines where it was executed. In most cases, this will
|
||||
be `/tmp` on Linux and `%temp%` on Windows. The agent searches a standard list
|
||||
of directories to find an appropriate place to store the log:
|
||||
|
||||
- Path on Linux: `/tmp/user-1563`
|
||||
- Path on Windows: `%temp%\\~df1563.tmp`
|
||||
1. The directory named by the `TMPDIR` environment variable.
|
||||
2. The directory named by the `TEMP` environment variable.
|
||||
3. The directory named by the `TMP` environment variable.
|
||||
4. A platform-specific location:
|
||||
- On Windows, the directories `C:\TEMP`, `C:\TMP`, `\TEMP`, and `\TMP`, in that order.
|
||||
- On all other platforms, the directories `/tmp`, `/var/tmp`, and `/usr/tmp`, in that order.
|
||||
5. As a last resort, the current working directory.
|
||||
|
||||
Infection Monkey log file name is constructed to the following pattern: `infection-monkey-agent-<TIMESTAMP>-<RANDOM_STRING>.log`
|
||||
|
||||
The logs contain information about the internals of the Infection Monkey agent's execution. The log will contain entries like these:
|
||||
|
||||
|
@ -216,9 +233,9 @@ The logs contain information about the internals of the Infection Monkey agent's
|
|||
|
||||
The Infection Monkey leaves hardly any trace on the target system. It will leave:
|
||||
|
||||
- Log files in the following locations:
|
||||
- Path on Linux: `/tmp/user-1563`
|
||||
- Path on Windows: `%temp%\\~df1563.tmp`
|
||||
- Log files in [temporary directories]({{< ref "/faq/#infection-monkey-agent-logs">}}):
|
||||
- Path on Linux: `/tmp/infection-monky-agent-<TIMESTAMP>-<RANDOM_STRING>.log`
|
||||
- Path on Windows: `%temp%\\infection-monky-agent-<TIMESTAMP>-<RANDOM_STRING>.log`
|
||||
|
||||
### What's the Infection Monkey Agent's impact on system resources usage?
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ You can take a look at [our roadmap](https://github.com/guardicore/monkey/projec
|
|||
|
||||
The best way to find weak spots in a network is by attacking it. The [*Adding Exploits*](./adding-exploits/) page will help you add exploits.
|
||||
|
||||
It's important to note that the Infection Monkey must be absolutely reliable. Otherwise, no one will use it, so avoid memory corruption exploits unless they're rock solid and focus on the logical vulns such as Shellshock.
|
||||
It's important to note that the Infection Monkey must be absolutely reliable. Otherwise, no one will use it, so avoid memory corruption exploits unless they're rock solid and focus on the logical vulns such as Hadoop.
|
||||
|
||||
### Analysis plugins 🔬
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ An exploit is a sequence of commands that takes advantage of a security vulnerab
|
|||
|
||||
### Do I need a new Exploit?
|
||||
|
||||
If all you want to do is execute a shell command, configure the required commands in the Monkey Island's post-breach action (PBA) configuration section or [add a new PBA](../adding-post-breach-actions/). If you would like the Infection Monkey agent to collect specific information, [add a new System Info Collector](../adding-system-info-collectors/).
|
||||
If all you want to do is execute a shell command, configure the required commands in the Monkey Island's post-breach action (PBA) configuration section or [add a new PBA](../adding-post-breach-actions/).
|
||||
|
||||
However, if you have your eye on an interesting CVE that you would like the Infection Monkey to support, you must add a new exploit. Keep reading to learn how to add a new exploit.
|
||||
|
||||
|
@ -39,7 +39,7 @@ class MyNewExploiter(HostExploiter):
|
|||
...
|
||||
```
|
||||
|
||||
A good example of an exploiter class is the [`SSHExploiter`](https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/exploit/sshexec.py). The [Drupal exploiter is a recently added web RCE exploit](https://github.com/guardicore/monkey/pull/808) that is a good reference as well.
|
||||
A good example of an exploiter class is the [`SSHExploiter`](https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/exploit/sshexec.py). The [Log4Shell exploiter is a recently added web RCE exploit](https://github.com/guardicore/monkey/pull/1670) that is a good reference as well.
|
||||
|
||||
|
||||
### Modify the Monkey Island
|
||||
|
@ -83,7 +83,7 @@ A good example of an exploiter class is the [`SSHExploiter`](https://github.com/
|
|||
"default": [
|
||||
"SmbExploiter",
|
||||
...
|
||||
"DrupalExploiter",
|
||||
"Log4ShellExploiter",
|
||||
"MyNewExploiter", <=================================
|
||||
],
|
||||
}
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
---
|
||||
title: "Adding System Info Collectors"
|
||||
date: 2020-06-09T11:03:42+03:00
|
||||
draft: false
|
||||
tags: ["contribute"]
|
||||
weight: 80
|
||||
---
|
||||
|
||||
## What does this guide cover?
|
||||
|
||||
This guide will show you how to create a new _System Info Collector_ for the Infection Monkey. System Info Collectors are modules that each of the Infection Monkey agents runs that collect specific information and send it back to the Monkey Island as part of the System Info Telemetry.
|
||||
|
||||
### Do I need a new System Info Collector?
|
||||
|
||||
If all you want to do is execute a shell command, then there's no need to add a new System Info Collector - just configure the required commands in the Monkey Island's post-breach action (PBA) section! Also, if there is a relevant System Info Collector and you only need to add more information to it, simply expand the existing one. Otherwise, you must add a new System Info Collector.
|
||||
|
||||
## How to add a new System Info Collector
|
||||
|
||||
### Modify the Infection Monkey Agent
|
||||
|
||||
#### Framework
|
||||
|
||||
1. Create your new System Info Collector in the following directory: `monkey/infection_monkey/system_info/collectors` by first creating a new file with the name of your System Info Collector.
|
||||
2. In that file, create a class that inherits from the `SystemInfoCollector` class:
|
||||
|
||||
```py
|
||||
from infection_monkey.system_info.system_info_collector import SystemInfoCollector
|
||||
|
||||
class MyNewCollector(SystemInfoCollector):
|
||||
```
|
||||
|
||||
3. Set the System Info Collector name in the constructor, like so:
|
||||
|
||||
```py
|
||||
class MyNewCollector(SystemInfoCollector):
|
||||
def __init__(self):
|
||||
super(MyNewCollector, self).__init__(name="MyNewCollector")
|
||||
```
|
||||
|
||||
#### Implementation
|
||||
|
||||
Override the `collect` method with your own implementation. See the `process_list_collector.py` System Info Collector for reference. You can log during collection as well.
|
||||
|
||||
### Modify the Monkey Island
|
||||
|
||||
#### Configuration
|
||||
|
||||
##### Definitions
|
||||
|
||||
You'll need to add your Sytem Info Collector to the `monkey_island/cc/services/config_schema.py` file, under `definitions/system_info_collectors_classes/anyOf`, like so:
|
||||
|
||||
```json
|
||||
"system_info_collectors_classes": {
|
||||
"title": "System Information Collectors",
|
||||
"type": "string",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"HostnameCollector"
|
||||
],
|
||||
"title": "Which Environment this machine is on (on prem/cloud)",
|
||||
"attack_techniques": []
|
||||
},
|
||||
{ <=================================
|
||||
"type": "string", <=================================
|
||||
"enum": [ <=================================
|
||||
"MyNewCollector" <=================================
|
||||
], <=================================
|
||||
"title": "My new title", <=================================
|
||||
"attack_techniques": [] <=================================
|
||||
},
|
||||
],
|
||||
},
|
||||
```
|
||||
|
||||
##### properties
|
||||
|
||||
Also, you can add the System Info Collector to be used by default by adding it to the `default` key under `properties/monkey/system_info/system_info_collectors_classes`:
|
||||
|
||||
```json
|
||||
"system_info_collectors_classes": {
|
||||
"title": "System info collectors",
|
||||
"type": "array",
|
||||
"uniqueItems": True,
|
||||
"items": {
|
||||
"$ref": "#/definitions/system_info_collectors_classes"
|
||||
},
|
||||
"default": [
|
||||
"HostnameCollector",
|
||||
"MyNewCollector" <=================================
|
||||
],
|
||||
"description": "Determines which system information collectors will collect information."
|
||||
},
|
||||
```
|
||||
|
||||
#### Telemetry processing
|
||||
|
||||
1. Add a process function under `monkey_island/cc/telemetry/processing/system_info_collectors/{DATA_NAME_HERE}.py`. The function should parse the System Info Collector's result. See `processing/system_info_collectors/environment.py` for example.
|
||||
|
||||
2. Add that function to `SYSTEM_INFO_COLLECTOR_TO_TELEMETRY_PROCESSORS` under `monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py`.
|
|
@ -16,7 +16,7 @@ The agent (which we sometimes refer to as the Infection Monkey) is a single Pyth
|
|||
|
||||
In order to compile the Infection Monkey for distribution by the Monkey Island, you'll need to run the instructions listed in the [`readme.txt`](https://github.com/guardicore/monkey/blob/master/monkey/infection_monkey/readme.txt) on each supported environment.
|
||||
|
||||
This means setting up an environment with Linux 32/64-bit with Python installed and a Windows 64-bit machine with developer tools, along with 32/64-bit Python versions.
|
||||
This means setting up an environment with Linux 64-bit with Python installed and a Windows 64-bit machine with developer tools, along with 64-bit Python versions.
|
||||
|
||||
## The Monkey Island
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
title: "Drupal"
|
||||
date: 2020-09-01T08:42:46+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "linux", "windows"]
|
||||
---
|
||||
|
||||
The Drupal exploiter exploits [CVE-2019-6340](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-6340)
|
||||
on a vulnerable Drupal server.
|
||||
|
||||
### Description
|
||||
|
||||
Some field types do not properly sanitize data from non-form sources in certain versions
|
||||
of Drupal server.
|
||||
|
||||
This can lead to arbitrary PHP code execution in some cases.
|
||||
|
||||
|
||||
### Affected Versions
|
||||
|
||||
* Drupal 8.5.x (before 8.5.11) and Drupal 8.6.x (before 8.6.10).
|
||||
|
||||
One of the following conditions must hold:
|
||||
* The site has the Drupal 8 core RESTful Web Services (rest) module enabled and allows PATCH
|
||||
or POST requests; OR
|
||||
* The site has another web services module enabled, like JSON:API in
|
||||
Drupal 8, or Services or RESTful Web Services in Drupal 7.
|
||||
|
||||
|
||||
### Notes
|
||||
|
||||
* The Infection Monkey exploiter implementation is based on an open-source
|
||||
[Python implementation](https://gist.github.com/leonjza/d0ab053be9b06fa020b66f00358e3d88/f9f6a5bb6605745e292bee3a4079f261d891738a)
|
||||
of the exploit by @leonjza.
|
||||
* For the full attack to work, more than one vulnerable URL is required.
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
title: "ElasticGroovy"
|
||||
date: 2020-07-14T08:41:40+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "windows", "linux"]
|
||||
---
|
||||
### Description
|
||||
|
||||
CVE-2015-1427
|
||||
|
||||
> The Groovy scripting engine in Elasticsearch before 1.3.8 and 1.4.x (before 1.4.3) allows remote attackers to bypass the sandbox protection mechanism and execute arbitrary shell commands via a crafted script.
|
||||
|
||||
The logic is based on the [Metasploit module](https://github.com/rapid7/metasploit-framework/blob/12198a088132f047e0a86724bc5ebba92a73ac66/modules/exploits/multi/elasticsearch/search_groovy_script.rb).
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
title: "MS08 067"
|
||||
date: 2020-07-14T08:42:54+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "windows"]
|
||||
---
|
||||
|
||||
### Description
|
||||
|
||||
[MS08-067](https://docs.microsoft.com/en-us/security-updates/securitybulletins/2008/ms08-067) is a remote code execution vulnerability.
|
||||
|
||||
This exploiter is unsafe. It's therefore **not** enabled by default.
|
||||
|
||||
If an exploit attempt fails, this could also lead to a crash in Svchost.exe. If a crash in Svchost.exe occurs, the server service will be affected. This may cause a system crash due to the use of buffer overflow.
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
title: "Struts2"
|
||||
date: 2020-07-14T08:42:30+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "linux", "windows"]
|
||||
---
|
||||
### Description
|
||||
|
||||
This exploit, CVE-2017-5638, utilizes the Struts 2 Java web framework. The logic is based on [VEX WOO's PoC](https://www.exploit-db.com/exploits/41570).
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
title: "WebLogic"
|
||||
date: 2020-07-14T08:42:46+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "linux", "windows"]
|
||||
---
|
||||
### Description
|
||||
|
||||
This exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on a vulnerable WebLogic server.
|
|
@ -1,11 +0,0 @@
|
|||
---
|
||||
title: "ShellShock"
|
||||
date: 2020-07-14T08:41:32+03:00
|
||||
draft: false
|
||||
tags: ["exploit", "linux"]
|
||||
---
|
||||
### Description
|
||||
|
||||
This exploit, CVE-2014-6271, is based on the [logic in NCC group's GitHub](https://github.com/nccgroup/shocker/blob/master/shocker.py).
|
||||
|
||||
> In GNU Bash (through 4.3), processes trailing strings after function definitions in the values of environment variables allow remote attackers to execute arbitrary code via a crafted environment. This is demonstrated by vectors involving the ForceCommand feature in OpenSSH sshd, the mod_cgi and mod_cgid modules in the Apache HTTP Server, scripts executed by unspecified DHCP clients and other situations in which setting the environment occurs across a privilege boundary from Bash execution, AKA "ShellShock."
|
|
@ -4,7 +4,7 @@ date: 2020-07-14T08:09:53+03:00
|
|||
draft: false
|
||||
pre: '<i class="fas fa-laptop"></i> '
|
||||
weight: 10
|
||||
tags: ["setup", "reference", "windows", "linux"]
|
||||
tags: ["setup", "reference", "windows", "linux"]
|
||||
---
|
||||
|
||||
The Infection Monkey project supports many popular OSes (but we are always interested in supporting more).
|
||||
|
@ -44,21 +44,4 @@ Compatibility depends on GLIBC version (2.14+)[^1]. By default, these distributi
|
|||
|
||||
We also provide a Dockerfile on our [website](http://infectionmonkey.com/) that lets the Monkey Island run inside a container.
|
||||
|
||||
### Old machine bootloader
|
||||
|
||||
Some **older machines** still have partial compatibility and will be exploited and reported, but the Infection Monkey agent can't run on them. In these cases, old machine bootloader (a small C program) will be run, which reports some minor info like network interface configuration, GLIBC version, OS, etc.
|
||||
|
||||
**Old machine bootloader** also has a GLIBC 2.14+ requirement for Linux because the bootloader is included in the Pyinstaller bootloader, which uses Python 3.7 that in turn requires GLIBC 2.14+. If you think partial support for older machines is important, don't hesitate to open a new issue about it.
|
||||
|
||||
**Old machine bootloader** runs on machines with:
|
||||
|
||||
- Centos 7+
|
||||
- Debian 7+
|
||||
- Kali 2019+
|
||||
- Oracle 7+
|
||||
- Rhel 7+
|
||||
- Suse 12+
|
||||
- Ubuntu 14+
|
||||
- **Windows XP/Server 2003+**
|
||||
|
||||
[^1]: The GLIBC >= 2.14 requirement exists because the Infection Monkey was built using this GLIBC version, and GLIBC is not backward compatible. We are also limited to the oldest GLIBC version compatible with Python 3.7.
|
||||
|
|
|
@ -29,14 +29,13 @@ The currently implemented Fingerprint modules are:
|
|||
2. [`SSHFinger`][ssh-finger] - Fingerprints target machines over SSH (port 22) and extracts the computer version and SSH banner.
|
||||
3. [`PingScanner`][ping-scanner] - Fingerprints target machine's TTL to differentiate between Linux and Windows hosts.
|
||||
4. [`HTTPFinger`][http-finger] - Detects HTTP/HTTPS services, using the ports listed in `HTTP_PORTS` in the configuration, will return the server type and if it supports SSL.
|
||||
5. [`MySQLFinger`][mysql-finger] - Fingerprints MySQL (port 3306) and will extract MySQL banner info - version, major/minor/build and capabilities.
|
||||
6. [`ElasticFinger`][elastic-finger] - Fingerprints ElasticSearch (port 9200) will extract the cluster name, node name and node version.
|
||||
5. [`ElasticFinger`][elastic-finger] - Fingerprints ElasticSearch (port 9200) and will extract the cluster name, node name and node version.
|
||||
|
||||
## Adding a scanner/fingerprinter
|
||||
|
||||
To add a new scanner/fingerprinter, create a new class that inherits from [`HostScanner`][host-scanner] or [`HostFinger`][host-finger] (depending on the interface). The class should be under the network module and imported under [`network/__init__.py`](https://github.com/guardicore/monkey/blob/master/monkey/infection_monkey/network/__init__.py).
|
||||
|
||||
To use the new scanner/fingerprinter by default, two files need to be changed - [`infection_monkey/config.py`](https://github.com/guardicore/monkey/blob/master/monkey/infection_monkey/config.py) and [`infection_monkey/example.conf`](https://github.com/guardicore/monkey/blob/master/monkey/infection_monkey/example.conf) to add references to the new class.
|
||||
To use the new scanner/fingerprinter by default, modify [`infection_monkey/config.py`](https://github.com/guardicore/monkey/blob/master/monkey/infection_monkey/config.py) to add references to the new class.
|
||||
|
||||
At this point, the Infection Monkey knows how to use the new scanner/fingerprinter but to make it easy to use, the UI needs to be updated. The relevant UI file is [`monkey_island/cc/services/config.py`](https://github.com/guardicore/monkey/blob/master/monkey/monkey_island/cc/services/config.py).
|
||||
|
||||
|
@ -44,7 +43,6 @@ At this point, the Infection Monkey knows how to use the new scanner/fingerprint
|
|||
[http-finger]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/httpfinger.py
|
||||
[host-finger]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/__init__.py
|
||||
[host-scanner]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/__init__.py
|
||||
[mysql-finger]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/mysqlfinger.py
|
||||
[ping-scanner]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/ping_scanner.py
|
||||
[smb-finger]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/smbfinger.py
|
||||
[ssh-finger]: https://github.com/guardicore/monkey/blob/develop/monkey/infection_monkey/network/sshfinger.py
|
||||
|
|
|
@ -52,7 +52,7 @@ You can configure the server by creating
|
|||
a [server configuration file](../../reference/server_configuration) and
|
||||
providing a path to it via command line parameters:
|
||||
|
||||
`./InfectionMonkey-v1.12.0.AppImage --server-config="/path/to/server_config.json"`
|
||||
`./InfectionMonkey-v1.13.0.AppImage --server-config="/path/to/server_config.json"`
|
||||
|
||||
### Start Monkey Island with user-provided certificate
|
||||
|
||||
|
@ -88,7 +88,7 @@ The server configuration file should look something like:
|
|||
|
||||
1. Start Monkey Island by running the Infection Monkey AppImage package:
|
||||
```bash
|
||||
./InfectionMonkey-v1.12.0.AppImage --server-config="/path/to/server_config.json"
|
||||
./InfectionMonkey-v1.13.0.AppImage --server-config="/path/to/server_config.json"
|
||||
```
|
||||
|
||||
1. Access the Monkey Island web UI by pointing your browser at
|
||||
|
@ -109,7 +109,7 @@ The server configuration file should look something like:
|
|||
|
||||
1. Start Monkey Island by running the Infection Monkey AppImage package:
|
||||
```bash
|
||||
./InfectionMonkey-v1.12.0.AppImage --server-config="/path/to/server_config.json"
|
||||
./InfectionMonkey-v1.13.0.AppImage --server-config="/path/to/server_config.json"
|
||||
```
|
||||
|
||||
1. Access the Monkey Island web UI by pointing your browser at
|
||||
|
|
|
@ -35,6 +35,19 @@ $ sha256sum monkey-linux-64
|
|||
|
||||
## Latest version checksums
|
||||
|
||||
| Filename | Type | Version | SHA256 |
|
||||
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
|
||||
| monkey-windows-64.exe | Windows Agent | 1.13.0 | `3EDD20DE2247047C8A822C84145981936CE2FD0BDF843EB5CA777CA4D2478B35` |
|
||||
| monkey-windows-32.exe | Windows Agent | 1.13.0 | `7497907E3CF4FFEB121A7795BFA16709800E6E0F99770F64AF7FFF684ECBA6D6` |
|
||||
| monkey-linux-64 | Linux Agent | 1.13.0 | `F21E709CB7BA8DAF90B908AF5FE485BA43866C325D3C7CE1EB07E8A2323E07C1` |
|
||||
| monkey-linux-32 | Linux Agent | 1.13.0 | `24C5779825F26C76A8910794836647096F4BB4B47CFD6AD213CC48116D140FAB` |
|
||||
| InfectionMonkey-v1.13.0.AppImage | Linux Package | 1.13.0 | `CDED4E8394A4D2A809BA9B74B924AEA590317515B9B032BA8005A93DFCE1C861` |
|
||||
| InfectionMonkey-docker-v1.13.0.tgz | Docker | 1.13.0 | `342701BA8EC5B754C59685896FC3DCDBB93362FFFAD0EC7F9E2E5B99DA26F5EC` |
|
||||
| InfectionMonkey-v1.13.0.exe | Windows Installer | 1.13.0 | `D35ED6CAF21AC786D9A438510282FA07AEF812590A5E6405A01F2B06661B33B9` |
|
||||
|
||||
|
||||
## Older checksums
|
||||
|
||||
| Filename | Type | Version | SHA256 |
|
||||
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
|
||||
| monkey-windows-64.exe | Windows Agent | 1.12.0 | `02e5e051a96e2ca61ae8e661b3a5828ee53a0fc00aca6502d5c73a46754f0d07` |
|
||||
|
@ -44,12 +57,6 @@ $ sha256sum monkey-linux-64
|
|||
| InfectionMonkey-v1.12.0.AppImage | Linux Package | 1.12.0 | `1325f2aa1d0c27aec2e2f9864ed53c53c524bd208313f87ea6606f59c90ff310` |
|
||||
| InfectionMonkey-docker-v1.12.0.tgz | Docker | 1.12.0 | `dcaf669411d55ea6883920597af4a35f3735a286801e08b6ef047cc91ff32769` |
|
||||
| InfectionMonkey-v1.12.0.exe | Windows Installer | 1.12.0 | `4d6e0373be3615a4b97721a07d2a854f6316d1ce8c4ff6d6495aac3a8f2c6a69` |
|
||||
|
||||
|
||||
## Older checksums
|
||||
|
||||
| Filename | Type | Version | SHA256 |
|
||||
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
|
||||
| monkey-windows-64.exe | Windows Agent | 1.11.0 | `12c55377381a8fc7d8ff731db52302ef2f8bb894d8712769e5a91a140ba22b0a` |
|
||||
| monkey-windows-32.exe | Windows Agent | 1.11.0 | `e006b26663f59b92bad8d49b034cd8101dd481f881e3c4839a9c1e64fd99e849` |
|
||||
| monkey-linux-64 | Linux Agent | 1.11.0 | `fb4c979ce6c29bb458be50a44cc6839650826b831da849da69a05dfefdc66462` |
|
||||
|
|
|
@ -7,11 +7,14 @@ pre: "<i class='fas fa-play-circle'></i> "
|
|||
tags: ["usage"]
|
||||
---
|
||||
|
||||
|
||||
<!-- TODO: Update screenshots -->
|
||||
|
||||
If you haven't deployed the Monkey Island yet, please [refer to our setup documentation](/setup).
|
||||
|
||||
## Using the Infection Monkey
|
||||
|
||||
After deploying the Monkey Island in your environment, navigate to `https://<server-ip>:5000`.
|
||||
After deploying the Monkey Island in your environment, navigate to `https://<server-ip>:5000`.
|
||||
|
||||
### First-time login
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
---
|
||||
title: "Scoutsuite"
|
||||
date: 2021-03-02T16:23:06+02:00
|
||||
draft: false
|
||||
description: "Scout Suite is an open-source cloud security-auditing tool."
|
||||
weight: 10
|
||||
---
|
||||
|
||||
### About ScoutSuite
|
||||
|
||||
<a href="https://github.com/nccgroup/ScoutSuite" target="_blank" >Scout Suite</a> is an open-source cloud security-auditing tool.
|
||||
It queries the cloud API to gather configuration data. Based on configuration
|
||||
data gathered, ScoutSuite shows security issues and risks present in your infrastructure.
|
||||
|
||||
### Supported cloud providers
|
||||
|
||||
Currently, ScoutSuite integration only supports AWS environments.
|
||||
|
||||
### Enabling ScoutSuite
|
||||
|
||||
First, Infection Monkey needs access to your cloud API. You can provide access
|
||||
in the following ways:
|
||||
|
||||
- Provide access keys:
|
||||
- Create a new user with ReadOnlyAccess and SecurityAudit policies and generate keys
|
||||
- Generate keys for your current user (faster but less secure)
|
||||
- Configure AWS CLI:
|
||||
- If the command-line interface is available on the Island, it will be used to access
|
||||
the cloud API
|
||||
|
||||
More details about configuring ScoutSuite can be found in the tool itself, by choosing
|
||||
"Cloud Security Scan" in the "Run Monkey" options.
|
||||
|
||||
![Cloud scan option in run page](/images/usage/integrations/scoutsuite_run_page.png
|
||||
"Successful setup indicator")
|
||||
|
||||
After you're done with the setup, make sure that a checkmark appears next to the AWS option. This
|
||||
verifies that ScoutSuite can access the API.
|
||||
|
||||
![Successfull setup indicator](/images/usage/integrations/scoutsuite_aws_configured.png
|
||||
"Successful setup indicator")
|
||||
|
||||
### Running a cloud security scan
|
||||
|
||||
If you have successfully configured the cloud scan, Infection Monkey will scan
|
||||
your cloud infrastructure when the Monkey Agent is run **on the Island**. You
|
||||
can simply click on "From Island" in the run options to start the scan. The
|
||||
scope of the network scan and other activities you may have configured the Agent
|
||||
to perform are ignored by the ScoutSuite integration, except **Monkey
|
||||
Configuration -> System info collectors -> AWS collector**, which needs to
|
||||
remain **enabled**.
|
||||
|
||||
|
||||
### Assessing scan results
|
||||
|
||||
After the scan is done, ScoutSuite results will be categorized according to the
|
||||
ZeroTrust Extended framework and displayed as a part of the ZeroTrust report.
|
||||
The main difference between Infection Monkey findings and ScoutSuite findings
|
||||
is that ScoutSuite findings contain security rules. To see which rules were
|
||||
checked, click on the "Rules" button next to the relevant test. You'll see a
|
||||
list of rule dropdowns that are color coded according to their status. Expand a
|
||||
rule to see its description, remediation and more details about resources
|
||||
flagged. Each flagged resource has a path so you can easily locate it in the
|
||||
cloud and remediate the issue.
|
||||
|
||||
![Open ScoutSuite rule](/images/usage/integrations/scoutsuite_report_rule.png
|
||||
"Successful setup indicator")
|
|
@ -11,8 +11,6 @@ weight: 1
|
|||
Want to assess your progress in achieving a Zero Trust network? The Infection Monkey can automatically evaluate your readiness across the different
|
||||
[Zero Trust Extended Framework](https://www.forrester.com/report/The+Zero+Trust+eXtended+ZTX+Ecosystem/-/E-RES137210) principles.
|
||||
|
||||
You can additionally scan your cloud infrastructure's compliance to ZeroTrust principles using [ScoutSuite integration.]({{< ref "/usage/integrations/scoutsuite" >}})
|
||||
|
||||
## Configuration
|
||||
|
||||
- **Exploits -> Credentials** This configuration value will be used for brute-forcing. The Infection Monkey uses the most popular default passwords and usernames, but feel free to adjust it according to the default passwords common in your network. Keep in mind a longer list means longer scanning times.
|
||||
|
|
|
@ -8,7 +8,7 @@ class BaseTemplate(ConfigTemplate):
|
|||
"basic.exploiters.exploiter_classes": [],
|
||||
"basic_network.scope.local_network_scan": False,
|
||||
"basic_network.scope.depth": 1,
|
||||
"internal.classes.finger_classes": ["PingScanner", "HTTPFinger"],
|
||||
"internal.classes.finger_classes": ["HTTPFinger"],
|
||||
"internal.monkey.system_info.system_info_collector_classes": [],
|
||||
"monkey.post_breach.post_breach_actions": [],
|
||||
"internal.general.keep_tunnel_open_time": 0,
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Drupal(ConfigTemplate):
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"internal.classes.finger_classes": ["PingScanner", "HTTPFinger"],
|
||||
"basic.exploiters.exploiter_classes": ["DrupalExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.28"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [80],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
}
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Elastic(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["ElasticGroovyExploiter"],
|
||||
"internal.classes.finger_classes": ["PingScanner", "HTTPFinger", "ElasticFinger"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.4", "10.2.2.5"],
|
||||
"basic_network.scope.depth": 1,
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [9200],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
}
|
||||
)
|
|
@ -0,0 +1,42 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Depth1A(ConfigTemplate):
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
# Tests:
|
||||
# Hadoop (10.2.2.2, 10.2.2.3)
|
||||
# Log4shell (10.2.3.55, 10.2.3.56, 10.2.3.49, 10.2.3.50, 10.2.3.51, 10.2.3.52)
|
||||
# MSSQL (10.2.2.16)
|
||||
# SMB mimikatz password stealing and brute force (10.2.2.14 and 10.2.2.15)
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": [
|
||||
"HadoopExploiter",
|
||||
"Log4ShellExploiter",
|
||||
"MSSQLExploiter",
|
||||
"SmbExploiter",
|
||||
"SSHExploiter",
|
||||
],
|
||||
"basic_network.scope.subnet_scan_list": [
|
||||
"10.2.2.2",
|
||||
"10.2.2.3",
|
||||
"10.2.3.55",
|
||||
"10.2.3.56",
|
||||
"10.2.3.49",
|
||||
"10.2.3.50",
|
||||
"10.2.3.51",
|
||||
"10.2.3.52",
|
||||
"10.2.2.16",
|
||||
"10.2.2.14",
|
||||
"10.2.2.15",
|
||||
],
|
||||
"basic.credentials.exploit_password_list": ["Ivrrw5zEzs", "Xk8VDTsC"],
|
||||
"basic.credentials.exploit_user_list": ["m0nk3y"],
|
||||
"monkey.system_info.system_info_collector_classes": [
|
||||
"MimikatzCollector",
|
||||
],
|
||||
}
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Depth2A(ConfigTemplate):
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
# SSH password and key brute-force, key stealing (10.2.2.11, 10.2.2.12)
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": [
|
||||
"SSHExploiter",
|
||||
],
|
||||
"basic_network.scope.subnet_scan_list": [
|
||||
"10.2.2.11",
|
||||
"10.2.2.12",
|
||||
],
|
||||
"basic_network.scope.depth": 2,
|
||||
"basic.credentials.exploit_password_list": ["^NgDvY59~8"],
|
||||
"basic.credentials.exploit_user_list": ["m0nk3y"],
|
||||
}
|
||||
)
|
|
@ -0,0 +1,48 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Depth3A(ConfigTemplate):
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
# Tests:
|
||||
# Powershell (10.2.3.45, 10.2.3.46, 10.2.3.47, 10.2.3.48)
|
||||
# Tunneling (SSH brute force) (10.2.2.9, 10.2.1.10, 10.2.0.12, 10.2.0.11)
|
||||
# WMI pass the hash (10.2.2.15)
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": [
|
||||
"PowerShellExploiter",
|
||||
"SSHExploiter",
|
||||
"WmiExploiter",
|
||||
],
|
||||
"basic_network.scope.subnet_scan_list": [
|
||||
"10.2.3.45",
|
||||
"10.2.3.46",
|
||||
"10.2.3.47",
|
||||
"10.2.3.48",
|
||||
"10.2.2.9",
|
||||
"10.2.1.10",
|
||||
"10.2.0.12",
|
||||
"10.2.0.11",
|
||||
"10.2.2.15",
|
||||
],
|
||||
"basic.credentials.exploit_password_list": [
|
||||
"Passw0rd!",
|
||||
"3Q=(Ge(+&w]*",
|
||||
"`))jU7L(w}",
|
||||
"t67TC5ZDmz",
|
||||
],
|
||||
"basic_network.scope.depth": 3,
|
||||
"internal.general.keep_tunnel_open_time": 20,
|
||||
"basic.credentials.exploit_user_list": ["m0nk3y", "m0nk3y-user"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.exploits.exploit_ntlm_hash_list": [
|
||||
"d0f0132b308a0c4e5d1029cc06f48692",
|
||||
"5da0889ea2081aa79f6852294cba4a5e",
|
||||
"50c9987a6bf1ac59398df9f911122c9b",
|
||||
],
|
||||
}
|
||||
)
|
|
@ -1,17 +0,0 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class ShellShock(ConfigTemplate):
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["ShellShockExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.8"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [80, 8080],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
}
|
||||
)
|
|
@ -10,7 +10,7 @@ class Mssql(ConfigTemplate):
|
|||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["MSSQLExploiter"],
|
||||
"internal.classes.finger_classes": ["PingScanner"],
|
||||
"internal.classes.finger_classes": [],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.16"],
|
||||
"basic.credentials.exploit_password_list": [
|
||||
"Password1!",
|
|
@ -16,10 +16,6 @@ class Performance(ConfigTemplate):
|
|||
"SmbExploiter",
|
||||
"WmiExploiter",
|
||||
"SSHExploiter",
|
||||
"ShellShockExploiter",
|
||||
"ElasticGroovyExploiter",
|
||||
"Struts2Exploiter",
|
||||
"WebLogicExploiter",
|
||||
"HadoopExploiter",
|
||||
"MSSQLExploiter",
|
||||
"PowerShellExploiter",
|
||||
|
@ -29,8 +25,6 @@ class Performance(ConfigTemplate):
|
|||
"basic_network.network_analysis.inaccessible_subnets": [
|
||||
"10.2.2.0/30",
|
||||
"10.2.2.8/30",
|
||||
"10.2.2.24/32",
|
||||
"10.2.2.23/32",
|
||||
"10.2.2.21/32",
|
||||
"10.2.2.19/32",
|
||||
"10.2.2.18/32",
|
||||
|
@ -55,8 +49,6 @@ class Performance(ConfigTemplate):
|
|||
"10.2.2.19",
|
||||
"10.2.2.20",
|
||||
"10.2.2.21",
|
||||
"10.2.2.23",
|
||||
"10.2.2.24",
|
||||
"10.2.2.25",
|
||||
"10.2.3.55",
|
||||
"10.2.3.56",
|
|
@ -19,9 +19,9 @@ class PowerShell(ConfigTemplate):
|
|||
"basic.credentials.exploit_password_list": ["Passw0rd!"],
|
||||
"basic_network.scope.depth": 2,
|
||||
"basic.credentials.exploit_user_list": ["m0nk3y", "m0nk3y-user"],
|
||||
"internal.classes.finger_classes": ["PingScanner"],
|
||||
"internal.classes.finger_classes": [],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [5985, 5986],
|
||||
"internal.exploits.exploit_ntlm_hash_list": [
|
||||
"d0f0132b308a0c4e5d1029cc06f48692",
|
||||
],
|
|
@ -14,8 +14,8 @@ class PowerShellCredentialsReuse(ConfigTemplate):
|
|||
"10.2.3.46",
|
||||
],
|
||||
"basic_network.scope.depth": 2,
|
||||
"internal.classes.finger_classes": ["PingScanner"],
|
||||
"internal.classes.finger_classes": [],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [5985, 5986],
|
||||
}
|
||||
)
|
|
@ -13,11 +13,10 @@ class SmbMimikatz(ConfigTemplate):
|
|||
"basic_network.scope.subnet_scan_list": ["10.2.2.14", "10.2.2.15"],
|
||||
"basic.credentials.exploit_password_list": ["Password1!", "Ivrrw5zEzs"],
|
||||
"basic.credentials.exploit_user_list": ["Administrator", "m0nk3y", "user"],
|
||||
"internal.classes.finger_classes": ["SMBFinger", "PingScanner", "HTTPFinger"],
|
||||
"internal.classes.finger_classes": ["SMBFinger", "HTTPFinger"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [445],
|
||||
"monkey.system_info.system_info_collector_classes": [
|
||||
"ProcessListCollector",
|
||||
"MimikatzCollector",
|
||||
],
|
||||
}
|
|
@ -13,7 +13,7 @@ class SmbPth(ConfigTemplate):
|
|||
"basic_network.scope.subnet_scan_list": ["10.2.2.15"],
|
||||
"basic.credentials.exploit_password_list": ["Password1!", "Ivrrw5zEzs"],
|
||||
"basic.credentials.exploit_user_list": ["Administrator", "m0nk3y", "user"],
|
||||
"internal.classes.finger_classes": ["SMBFinger", "PingScanner", "HTTPFinger"],
|
||||
"internal.classes.finger_classes": ["SMBFinger", "HTTPFinger"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [445],
|
||||
"internal.classes.exploits.exploit_ntlm_hash_list": [
|
|
@ -14,7 +14,7 @@ class Ssh(ConfigTemplate):
|
|||
"basic.credentials.exploit_password_list": ["Password1!", "12345678", "^NgDvY59~8"],
|
||||
"basic_network.scope.depth": 2,
|
||||
"basic.credentials.exploit_user_list": ["Administrator", "m0nk3y", "user"],
|
||||
"internal.classes.finger_classes": ["SSHFinger", "PingScanner"],
|
||||
"internal.classes.finger_classes": ["SSHFinger"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [22],
|
||||
}
|
|
@ -17,7 +17,7 @@ class Tunneling(ConfigTemplate):
|
|||
"10.2.0.11",
|
||||
],
|
||||
"basic_network.scope.depth": 3,
|
||||
"internal.general.keep_tunnel_open_time": 150,
|
||||
"internal.general.keep_tunnel_open_time": 20,
|
||||
"basic.credentials.exploit_password_list": [
|
||||
"Password1!",
|
||||
"3Q=(Ge(+&w]*",
|
||||
|
@ -28,7 +28,6 @@ class Tunneling(ConfigTemplate):
|
|||
"basic.credentials.exploit_user_list": ["Administrator", "m0nk3y", "user"],
|
||||
"internal.classes.finger_classes": [
|
||||
"SSHFinger",
|
||||
"PingScanner",
|
||||
"HTTPFinger",
|
||||
"SMBFinger",
|
||||
],
|
|
@ -16,7 +16,6 @@ class WmiMimikatz(ConfigTemplate):
|
|||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [135],
|
||||
"monkey.system_info.system_info_collector_classes": [
|
||||
"ProcessListCollector",
|
||||
"MimikatzCollector",
|
||||
],
|
||||
}
|
|
@ -13,7 +13,7 @@ class WmiPth(ConfigTemplate):
|
|||
"basic_network.scope.subnet_scan_list": ["10.2.2.15"],
|
||||
"basic.credentials.exploit_password_list": ["Password1!"],
|
||||
"basic.credentials.exploit_user_list": ["Administrator", "m0nk3y", "user"],
|
||||
"internal.classes.finger_classes": ["PingScanner", "HTTPFinger"],
|
||||
"internal.classes.finger_classes": ["HTTPFinger"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [135],
|
||||
"internal.exploits.exploit_ntlm_hash_list": [
|
|
@ -1,19 +0,0 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Struts2(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["Struts2Exploiter"],
|
||||
"basic_network.scope.depth": 2,
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.23", "10.2.2.24"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [80, 8080],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [80, 8080],
|
||||
}
|
||||
)
|
|
@ -1,18 +0,0 @@
|
|||
from copy import copy
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.base_template import BaseTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
|
||||
|
||||
class Weblogic(ConfigTemplate):
|
||||
|
||||
config_values = copy(BaseTemplate.config_values)
|
||||
|
||||
config_values.update(
|
||||
{
|
||||
"basic.exploiters.exploiter_classes": ["WebLogicExploiter"],
|
||||
"basic_network.scope.subnet_scan_list": ["10.2.2.18", "10.2.2.19"],
|
||||
"internal.network.tcp_scanner.HTTP_PORTS": [7001],
|
||||
"internal.network.tcp_scanner.tcp_target_ports": [],
|
||||
}
|
||||
)
|
|
@ -2,24 +2,16 @@ GCP_TEST_MACHINE_LIST = {
|
|||
"europe-west3-a": [
|
||||
"sshkeys-11",
|
||||
"sshkeys-12",
|
||||
"elastic-4",
|
||||
"elastic-5",
|
||||
"hadoop-2",
|
||||
"hadoop-3",
|
||||
"mssql-16",
|
||||
"mimikatz-14",
|
||||
"mimikatz-15",
|
||||
"struts2-23",
|
||||
"struts2-24",
|
||||
"tunneling-9",
|
||||
"tunneling-10",
|
||||
"tunneling-11",
|
||||
"tunneling-12",
|
||||
"weblogic-18",
|
||||
"weblogic-19",
|
||||
"shellshock-8",
|
||||
"zerologon-25",
|
||||
"drupal-28",
|
||||
],
|
||||
"europe-west1-b": [
|
||||
"powershell-3-45",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
import logging
|
||||
from time import sleep
|
||||
import time
|
||||
from typing import Union
|
||||
|
||||
from bson import json_util
|
||||
|
@ -15,7 +15,7 @@ LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def avoid_race_condition(func):
|
||||
sleep(SLEEP_BETWEEN_REQUESTS_SECONDS)
|
||||
time.sleep(SLEEP_BETWEEN_REQUESTS_SECONDS)
|
||||
return func
|
||||
|
||||
|
||||
|
@ -48,10 +48,15 @@ class MonkeyIslandClient(object):
|
|||
|
||||
@avoid_race_condition
|
||||
def kill_all_monkeys(self):
|
||||
if self.requests.get("api", {"action": "killall"}).ok:
|
||||
response = self.requests.post_json(
|
||||
"api/monkey_control/stop-all-agents", data={"kill_time": time.time()}
|
||||
)
|
||||
if response.ok:
|
||||
LOGGER.info("Killing all monkeys after the test.")
|
||||
else:
|
||||
LOGGER.error("Failed to kill all monkeys.")
|
||||
LOGGER.error(response.status_code)
|
||||
LOGGER.error(response.content)
|
||||
assert False
|
||||
|
||||
@avoid_race_condition
|
||||
|
|
|
@ -8,44 +8,20 @@ from typing_extensions import Type
|
|||
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer
|
||||
from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZerologonAnalyzer
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
|
||||
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
|
||||
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat
|
||||
from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql
|
||||
from envs.monkey_zoo.blackbox.config_templates.performance import Performance
|
||||
from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell
|
||||
from envs.monkey_zoo.blackbox.config_templates.powershell_credentials_reuse import (
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_1_a import Depth1A
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_2_a import Depth2A
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_3_a import Depth3A
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import (
|
||||
PowerShellCredentialsReuse,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.config_templates.shellshock import ShellShock
|
||||
from envs.monkey_zoo.blackbox.config_templates.smb_mimikatz import SmbMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.smb_pth import SmbPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.ssh import Ssh
|
||||
from envs.monkey_zoo.blackbox.config_templates.struts2 import Struts2
|
||||
from envs.monkey_zoo.blackbox.config_templates.tunneling import Tunneling
|
||||
from envs.monkey_zoo.blackbox.config_templates.weblogic import Weblogic
|
||||
from envs.monkey_zoo.blackbox.config_templates.wmi_mimikatz import WmiMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.wmi_pth import WmiPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.zerologon import Zerologon
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon
|
||||
from envs.monkey_zoo.blackbox.gcp_test_machine_list import GCP_TEST_MACHINE_LIST
|
||||
from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser
|
||||
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler
|
||||
from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.map_generation import MapGenerationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.map_generation_from_telemetries import (
|
||||
MapGenerationFromTelemetryTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.tests.performance.report_generation import ReportGenerationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.report_generation_from_telemetries import (
|
||||
ReportGenerationFromTelemetryTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.tests.performance.telemetry_performance_test import (
|
||||
TelemetryPerformanceTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import (
|
||||
initialize_gcp_client,
|
||||
start_machines,
|
||||
|
@ -53,7 +29,7 @@ from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import (
|
|||
)
|
||||
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
||||
|
||||
DEFAULT_TIMEOUT_SECONDS = 5 * 60
|
||||
DEFAULT_TIMEOUT_SECONDS = 2 * 60 + 30
|
||||
MACHINE_BOOTUP_WAIT_SECONDS = 30
|
||||
LOG_DIR_PATH = "./logs"
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
@ -130,48 +106,20 @@ class TestMonkeyBlackbox:
|
|||
log_handler=log_handler,
|
||||
).run()
|
||||
|
||||
@staticmethod
|
||||
def run_performance_test(
|
||||
performance_test_class,
|
||||
island_client,
|
||||
config_template,
|
||||
timeout_in_seconds,
|
||||
break_on_timeout=False,
|
||||
):
|
||||
raw_config = IslandConfigParser.get_raw_config(config_template, island_client)
|
||||
log_handler = TestLogsHandler(
|
||||
performance_test_class.TEST_NAME, island_client, TestMonkeyBlackbox.get_log_dir_path()
|
||||
)
|
||||
analyzers = [
|
||||
CommunicationAnalyzer(island_client, IslandConfigParser.get_ips_of_targets(raw_config))
|
||||
]
|
||||
performance_test_class(
|
||||
island_client=island_client,
|
||||
raw_config=raw_config,
|
||||
analyzers=analyzers,
|
||||
timeout=timeout_in_seconds,
|
||||
log_handler=log_handler,
|
||||
break_on_timeout=break_on_timeout,
|
||||
).run()
|
||||
|
||||
@staticmethod
|
||||
def get_log_dir_path():
|
||||
return os.path.abspath(LOG_DIR_PATH)
|
||||
|
||||
def test_ssh_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Ssh, "SSH_exploiter_and_keys")
|
||||
def test_depth_1_a(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Depth1A, "Depth1A test suite")
|
||||
|
||||
def test_hadoop_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Hadoop, "Hadoop_exploiter", 6 * 60)
|
||||
def test_depth_2_a(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Depth2A, "Depth2A test suite")
|
||||
|
||||
def test_mssql_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Mssql, "MSSQL_exploiter")
|
||||
|
||||
def test_powershell_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, PowerShell, "PowerShell_Remoting_exploiter"
|
||||
)
|
||||
def test_depth_3_a(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Depth3A, "Depth3A test suite")
|
||||
|
||||
# Not grouped because can only be ran on windows
|
||||
@pytest.mark.skip_powershell_reuse
|
||||
def test_powershell_exploiter_credentials_reuse(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
|
@ -180,57 +128,7 @@ class TestMonkeyBlackbox:
|
|||
"PowerShell_Remoting_exploiter_credentials_reuse",
|
||||
)
|
||||
|
||||
def test_smb_and_mimikatz_exploiters(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, SmbMimikatz, "SMB_exploiter_mimikatz"
|
||||
)
|
||||
|
||||
def test_smb_pth(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH")
|
||||
|
||||
def test_drupal_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Drupal, "Drupal_exploiter")
|
||||
|
||||
def test_elastic_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Elastic, "Elastic_exploiter")
|
||||
|
||||
def test_struts_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Struts2, "Struts2_exploiter")
|
||||
|
||||
def test_weblogic_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Weblogic, "Weblogic_exploiter")
|
||||
|
||||
def test_shellshock_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, ShellShock, "Shellshock_exploiter")
|
||||
|
||||
def test_log4j_solr_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jSolr, "Log4Shell_Solr_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_tomcat_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_logstash_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jLogstash, "Log4Shell_logstash_exploiter"
|
||||
)
|
||||
|
||||
def test_tunneling(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Tunneling, "Tunneling_exploiter", 15 * 60
|
||||
)
|
||||
|
||||
def test_wmi_and_mimikatz_exploiters(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, WmiMimikatz, "WMI_exploiter,_mimikatz"
|
||||
)
|
||||
|
||||
def test_wmi_pth(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH")
|
||||
|
||||
# Not grouped because it's slow
|
||||
def test_zerologon_exploiter(self, island_client):
|
||||
test_name = "Zerologon_exploiter"
|
||||
expected_creds = [
|
||||
|
@ -255,47 +153,13 @@ class TestMonkeyBlackbox:
|
|||
log_handler=log_handler,
|
||||
).run()
|
||||
|
||||
@pytest.mark.skip(
|
||||
reason="Perfomance test that creates env from fake telemetries is faster, use that instead."
|
||||
)
|
||||
def test_report_generation_performance(self, island_client, quick_performance_tests):
|
||||
"""
|
||||
This test includes the SSH + Elastic + Hadoop + MSSQL machines all in one test
|
||||
for a total of 8 machines including the Monkey Island.
|
||||
# Not grouped because conflicts with SMB.
|
||||
# Consider grouping when more depth 1 exploiters collide with group depth_1_a
|
||||
def test_wmi_and_mimikatz_exploiters(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, WmiMimikatz, "WMI_exploiter,_mimikatz"
|
||||
)
|
||||
|
||||
Is has 2 analyzers - the regular one which checks all the Monkeys
|
||||
and the Timing one which checks how long the report took to execute
|
||||
"""
|
||||
if not quick_performance_tests:
|
||||
TestMonkeyBlackbox.run_performance_test(
|
||||
ReportGenerationTest, island_client, Performance, timeout_in_seconds=10 * 60
|
||||
)
|
||||
else:
|
||||
LOGGER.error("This test doesn't support 'quick_performance_tests' option.")
|
||||
assert False
|
||||
|
||||
@pytest.mark.skip(
|
||||
reason="Perfomance test that creates env from fake telemetries is faster, use that instead."
|
||||
)
|
||||
def test_map_generation_performance(self, island_client, quick_performance_tests):
|
||||
if not quick_performance_tests:
|
||||
TestMonkeyBlackbox.run_performance_test(
|
||||
MapGenerationTest, island_client, "PERFORMANCE.conf", timeout_in_seconds=10 * 60
|
||||
)
|
||||
else:
|
||||
LOGGER.error("This test doesn't support 'quick_performance_tests' option.")
|
||||
assert False
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_report_generation_from_fake_telemetries(self, island_client, quick_performance_tests):
|
||||
ReportGenerationFromTelemetryTest(island_client, quick_performance_tests).run()
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_map_generation_from_fake_telemetries(self, island_client, quick_performance_tests):
|
||||
MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run()
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_telem_performance(self, island_client, quick_performance_tests):
|
||||
TelemetryPerformanceTest(
|
||||
island_client, quick_performance_tests
|
||||
).test_telemetry_performance()
|
||||
# Not grouped because it's depth 1 but conflicts with SMB exploiter in group depth_1_a
|
||||
def test_smb_pth(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH")
|
||||
|
|
|
@ -0,0 +1,296 @@
|
|||
import logging
|
||||
import os
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from typing_extensions import Type
|
||||
|
||||
from envs.monkey_zoo.blackbox.analyzers.communication_analyzer import CommunicationAnalyzer
|
||||
from envs.monkey_zoo.blackbox.analyzers.zerologon_analyzer import ZerologonAnalyzer
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.drupal import Drupal
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.hadoop import Hadoop
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_logstash import Log4jLogstash
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_solr import Log4jSolr
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.log4j_tomcat import Log4jTomcat
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.mssql import Mssql
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.performance import Performance
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell import PowerShell
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import (
|
||||
PowerShellCredentialsReuse,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_mimikatz import SmbMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.ssh import Ssh
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.struts2 import Struts2
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.tunneling import Tunneling
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.weblogic import Weblogic
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_pth import WmiPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon
|
||||
from envs.monkey_zoo.blackbox.gcp_test_machine_list import GCP_TEST_MACHINE_LIST
|
||||
from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser
|
||||
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient
|
||||
from envs.monkey_zoo.blackbox.log_handlers.test_logs_handler import TestLogsHandler
|
||||
from envs.monkey_zoo.blackbox.tests.exploitation import ExploitationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.map_generation import MapGenerationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.map_generation_from_telemetries import (
|
||||
MapGenerationFromTelemetryTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.tests.performance.report_generation import ReportGenerationTest
|
||||
from envs.monkey_zoo.blackbox.tests.performance.report_generation_from_telemetries import (
|
||||
ReportGenerationFromTelemetryTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.tests.performance.telemetry_performance_test import (
|
||||
TelemetryPerformanceTest,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.utils.gcp_machine_handlers import (
|
||||
initialize_gcp_client,
|
||||
start_machines,
|
||||
stop_machines,
|
||||
)
|
||||
from monkey_island.cc.services.mode.mode_enum import IslandModeEnum
|
||||
|
||||
DEFAULT_TIMEOUT_SECONDS = 2 * 60
|
||||
MACHINE_BOOTUP_WAIT_SECONDS = 30
|
||||
LOG_DIR_PATH = "./logs"
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="session")
|
||||
def GCPHandler(request, no_gcp):
|
||||
if not no_gcp:
|
||||
try:
|
||||
initialize_gcp_client()
|
||||
start_machines(GCP_TEST_MACHINE_LIST)
|
||||
except Exception as e:
|
||||
LOGGER.error("GCP Handler failed to initialize: %s." % e)
|
||||
pytest.exit("Encountered an error while starting GCP machines. Stopping the tests.")
|
||||
wait_machine_bootup()
|
||||
|
||||
def fin():
|
||||
stop_machines(GCP_TEST_MACHINE_LIST)
|
||||
|
||||
request.addfinalizer(fin)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="session")
|
||||
def delete_logs():
|
||||
LOGGER.info("Deleting monkey logs before new tests.")
|
||||
TestLogsHandler.delete_log_folder_contents(TestMonkeyBlackbox.get_log_dir_path())
|
||||
|
||||
|
||||
def wait_machine_bootup():
|
||||
sleep(MACHINE_BOOTUP_WAIT_SECONDS)
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def island_client(island, quick_performance_tests):
|
||||
client_established = False
|
||||
try:
|
||||
island_client_object = MonkeyIslandClient(island)
|
||||
client_established = island_client_object.get_api_status()
|
||||
except Exception:
|
||||
logging.exception("Got an exception while trying to establish connection to the Island.")
|
||||
finally:
|
||||
if not client_established:
|
||||
pytest.exit("BB tests couldn't establish communication to the island.")
|
||||
if not quick_performance_tests:
|
||||
island_client_object.reset_env()
|
||||
island_client_object.set_scenario(IslandModeEnum.ADVANCED.value)
|
||||
yield island_client_object
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("island_client")
|
||||
# noinspection PyUnresolvedReferences
|
||||
class TestMonkeyBlackbox:
|
||||
@staticmethod
|
||||
def run_exploitation_test(
|
||||
island_client: MonkeyIslandClient,
|
||||
config_template: Type[ConfigTemplate],
|
||||
test_name: str,
|
||||
timeout_in_seconds=DEFAULT_TIMEOUT_SECONDS,
|
||||
):
|
||||
raw_config = IslandConfigParser.get_raw_config(config_template, island_client)
|
||||
analyzer = CommunicationAnalyzer(
|
||||
island_client, IslandConfigParser.get_ips_of_targets(raw_config)
|
||||
)
|
||||
log_handler = TestLogsHandler(
|
||||
test_name, island_client, TestMonkeyBlackbox.get_log_dir_path()
|
||||
)
|
||||
ExploitationTest(
|
||||
name=test_name,
|
||||
island_client=island_client,
|
||||
raw_config=raw_config,
|
||||
analyzers=[analyzer],
|
||||
timeout=timeout_in_seconds,
|
||||
log_handler=log_handler,
|
||||
).run()
|
||||
|
||||
@staticmethod
|
||||
def run_performance_test(
|
||||
performance_test_class,
|
||||
island_client,
|
||||
config_template,
|
||||
timeout_in_seconds,
|
||||
break_on_timeout=False,
|
||||
):
|
||||
raw_config = IslandConfigParser.get_raw_config(config_template, island_client)
|
||||
log_handler = TestLogsHandler(
|
||||
performance_test_class.TEST_NAME, island_client, TestMonkeyBlackbox.get_log_dir_path()
|
||||
)
|
||||
analyzers = [
|
||||
CommunicationAnalyzer(island_client, IslandConfigParser.get_ips_of_targets(raw_config))
|
||||
]
|
||||
performance_test_class(
|
||||
island_client=island_client,
|
||||
raw_config=raw_config,
|
||||
analyzers=analyzers,
|
||||
timeout=timeout_in_seconds,
|
||||
log_handler=log_handler,
|
||||
break_on_timeout=break_on_timeout,
|
||||
).run()
|
||||
|
||||
@staticmethod
|
||||
def get_log_dir_path():
|
||||
return os.path.abspath(LOG_DIR_PATH)
|
||||
|
||||
def test_ssh_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Ssh, "SSH_exploiter_and_keys")
|
||||
|
||||
def test_hadoop_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Hadoop, "Hadoop_exploiter", 6 * 60)
|
||||
|
||||
def test_mssql_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Mssql, "MSSQL_exploiter")
|
||||
|
||||
def test_powershell_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, PowerShell, "PowerShell_Remoting_exploiter"
|
||||
)
|
||||
|
||||
@pytest.mark.skip_powershell_reuse
|
||||
def test_powershell_exploiter_credentials_reuse(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client,
|
||||
PowerShellCredentialsReuse,
|
||||
"PowerShell_Remoting_exploiter_credentials_reuse",
|
||||
)
|
||||
|
||||
def test_smb_and_mimikatz_exploiters(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, SmbMimikatz, "SMB_exploiter_mimikatz"
|
||||
)
|
||||
|
||||
def test_smb_pth(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, SmbPth, "SMB_PTH")
|
||||
|
||||
@pytest.mark.skip(reason="Drupal exploiter is deprecated")
|
||||
def test_drupal_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Drupal, "Drupal_exploiter")
|
||||
|
||||
@pytest.mark.skip(reason="Struts2 exploiter is deprecated")
|
||||
def test_struts_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Struts2, "Struts2_exploiter")
|
||||
|
||||
@pytest.mark.skip(reason="Weblogic exploiter is deprecated")
|
||||
def test_weblogic_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, Weblogic, "Weblogic_exploiter")
|
||||
|
||||
def test_log4j_solr_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jSolr, "Log4Shell_Solr_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_tomcat_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jTomcat, "Log4Shell_tomcat_exploiter"
|
||||
)
|
||||
|
||||
def test_log4j_logstash_exploiter(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Log4jLogstash, "Log4Shell_logstash_exploiter"
|
||||
)
|
||||
|
||||
def test_tunneling(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, Tunneling, "Tunneling_exploiter", 3 * 60
|
||||
)
|
||||
|
||||
def test_wmi_and_mimikatz_exploiters(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(
|
||||
island_client, WmiMimikatz, "WMI_exploiter,_mimikatz"
|
||||
)
|
||||
|
||||
def test_wmi_pth(self, island_client):
|
||||
TestMonkeyBlackbox.run_exploitation_test(island_client, WmiPth, "WMI_PTH")
|
||||
|
||||
def test_zerologon_exploiter(self, island_client):
|
||||
test_name = "Zerologon_exploiter"
|
||||
expected_creds = [
|
||||
"Administrator",
|
||||
"aad3b435b51404eeaad3b435b51404ee",
|
||||
"2864b62ea4496934a5d6e86f50b834a5",
|
||||
]
|
||||
raw_config = IslandConfigParser.get_raw_config(Zerologon, island_client)
|
||||
zero_logon_analyzer = ZerologonAnalyzer(island_client, expected_creds)
|
||||
communication_analyzer = CommunicationAnalyzer(
|
||||
island_client, IslandConfigParser.get_ips_of_targets(raw_config)
|
||||
)
|
||||
log_handler = TestLogsHandler(
|
||||
test_name, island_client, TestMonkeyBlackbox.get_log_dir_path()
|
||||
)
|
||||
ExploitationTest(
|
||||
name=test_name,
|
||||
island_client=island_client,
|
||||
raw_config=raw_config,
|
||||
analyzers=[zero_logon_analyzer, communication_analyzer],
|
||||
timeout=DEFAULT_TIMEOUT_SECONDS,
|
||||
log_handler=log_handler,
|
||||
).run()
|
||||
|
||||
@pytest.mark.skip(
|
||||
reason="Perfomance test that creates env from fake telemetries is faster, use that instead."
|
||||
)
|
||||
def test_report_generation_performance(self, island_client, quick_performance_tests):
|
||||
"""
|
||||
This test includes the SSH + Hadoop + MSSQL machines all in one test
|
||||
for a total of 8 machines including the Monkey Island.
|
||||
|
||||
Is has 2 analyzers - the regular one which checks all the Monkeys
|
||||
and the Timing one which checks how long the report took to execute
|
||||
"""
|
||||
if not quick_performance_tests:
|
||||
TestMonkeyBlackbox.run_performance_test(
|
||||
ReportGenerationTest, island_client, Performance, timeout_in_seconds=10 * 60
|
||||
)
|
||||
else:
|
||||
LOGGER.error("This test doesn't support 'quick_performance_tests' option.")
|
||||
assert False
|
||||
|
||||
@pytest.mark.skip(
|
||||
reason="Perfomance test that creates env from fake telemetries is faster, use that instead."
|
||||
)
|
||||
def test_map_generation_performance(self, island_client, quick_performance_tests):
|
||||
if not quick_performance_tests:
|
||||
TestMonkeyBlackbox.run_performance_test(
|
||||
MapGenerationTest, island_client, "PERFORMANCE.conf", timeout_in_seconds=10 * 60
|
||||
)
|
||||
else:
|
||||
LOGGER.error("This test doesn't support 'quick_performance_tests' option.")
|
||||
assert False
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_report_generation_from_fake_telemetries(self, island_client, quick_performance_tests):
|
||||
ReportGenerationFromTelemetryTest(island_client, quick_performance_tests).run()
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_map_generation_from_fake_telemetries(self, island_client, quick_performance_tests):
|
||||
MapGenerationFromTelemetryTest(island_client, quick_performance_tests).run()
|
||||
|
||||
@pytest.mark.run_performance_tests
|
||||
def test_telem_performance(self, island_client, quick_performance_tests):
|
||||
TelemetryPerformanceTest(
|
||||
island_client, quick_performance_tests
|
||||
).test_telemetry_performance()
|
|
@ -5,10 +5,10 @@ from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandCo
|
|||
from envs.monkey_zoo.blackbox.tests.basic_test import BasicTest
|
||||
from envs.monkey_zoo.blackbox.utils.test_timer import TestTimer
|
||||
|
||||
MAX_TIME_FOR_MONKEYS_TO_DIE = 5 * 60
|
||||
WAIT_TIME_BETWEEN_REQUESTS = 5
|
||||
TIME_FOR_MONKEY_PROCESS_TO_FINISH = 10
|
||||
DELAY_BETWEEN_ANALYSIS = 3
|
||||
MAX_TIME_FOR_MONKEYS_TO_DIE = 2 * 60
|
||||
WAIT_TIME_BETWEEN_REQUESTS = 1
|
||||
TIME_FOR_MONKEY_PROCESS_TO_FINISH = 5
|
||||
DELAY_BETWEEN_ANALYSIS = 1
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -89,6 +89,7 @@ class ExploitationTest(BasicTest):
|
|||
if time_passed > MAX_TIME_FOR_MONKEYS_TO_DIE:
|
||||
LOGGER.error("Some monkeys didn't die after the test, failing")
|
||||
assert False
|
||||
LOGGER.info(f"After {time_passed} seconds all monkeys have died")
|
||||
|
||||
def parse_logs(self):
|
||||
LOGGER.info("Parsing test logs:")
|
||||
|
|
|
@ -3,25 +3,15 @@ import pathlib
|
|||
from typing import Type
|
||||
|
||||
from envs.monkey_zoo.blackbox.config_templates.config_template import ConfigTemplate
|
||||
from envs.monkey_zoo.blackbox.config_templates.drupal import Drupal
|
||||
from envs.monkey_zoo.blackbox.config_templates.elastic import Elastic
|
||||
from envs.monkey_zoo.blackbox.config_templates.hadoop import Hadoop
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_logstash import Log4jLogstash
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_solr import Log4jSolr
|
||||
from envs.monkey_zoo.blackbox.config_templates.log4j_tomcat import Log4jTomcat
|
||||
from envs.monkey_zoo.blackbox.config_templates.mssql import Mssql
|
||||
from envs.monkey_zoo.blackbox.config_templates.performance import Performance
|
||||
from envs.monkey_zoo.blackbox.config_templates.powershell import PowerShell
|
||||
from envs.monkey_zoo.blackbox.config_templates.shellshock import ShellShock
|
||||
from envs.monkey_zoo.blackbox.config_templates.smb_mimikatz import SmbMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.smb_pth import SmbPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.ssh import Ssh
|
||||
from envs.monkey_zoo.blackbox.config_templates.struts2 import Struts2
|
||||
from envs.monkey_zoo.blackbox.config_templates.tunneling import Tunneling
|
||||
from envs.monkey_zoo.blackbox.config_templates.weblogic import Weblogic
|
||||
from envs.monkey_zoo.blackbox.config_templates.wmi_mimikatz import WmiMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.wmi_pth import WmiPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.zerologon import Zerologon
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_1_a import Depth1A
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_2_a import Depth2A
|
||||
from envs.monkey_zoo.blackbox.config_templates.grouped.depth_3_a import Depth3A
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.powershell_credentials_reuse import (
|
||||
PowerShellCredentialsReuse,
|
||||
)
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.smb_pth import SmbPth
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.wmi_mimikatz import WmiMimikatz
|
||||
from envs.monkey_zoo.blackbox.config_templates.single_tests.zerologon import Zerologon
|
||||
from envs.monkey_zoo.blackbox.island_client.island_config_parser import IslandConfigParser
|
||||
from envs.monkey_zoo.blackbox.island_client.monkey_island_client import MonkeyIslandClient
|
||||
|
||||
|
@ -38,27 +28,14 @@ parser.add_argument(
|
|||
args = parser.parse_args()
|
||||
island_client = MonkeyIslandClient(args.island_ip)
|
||||
|
||||
|
||||
CONFIG_TEMPLATES = [
|
||||
Elastic,
|
||||
Hadoop,
|
||||
Mssql,
|
||||
Performance,
|
||||
PowerShell,
|
||||
ShellShock,
|
||||
SmbMimikatz,
|
||||
SmbPth,
|
||||
Ssh,
|
||||
Struts2,
|
||||
Tunneling,
|
||||
Weblogic,
|
||||
WmiMimikatz,
|
||||
WmiPth,
|
||||
Depth1A,
|
||||
Depth2A,
|
||||
Depth3A,
|
||||
Zerologon,
|
||||
Drupal,
|
||||
Log4jLogstash,
|
||||
Log4jTomcat,
|
||||
Log4jSolr,
|
||||
SmbPth,
|
||||
WmiMimikatz,
|
||||
PowerShellCredentialsReuse,
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@ This document describes Infection Monkey’s test network, how to deploy and use
|
|||
[Machines](#machines)<br>
|
||||
[Nr. 2 Hadoop](#_Toc526517182)<br>
|
||||
[Nr. 3 Hadoop](#_Toc526517183)<br>
|
||||
[Nr. 4 Elastic](#_Toc526517184)<br>
|
||||
[Nr. 5 Elastic](#_Toc526517185)<br>
|
||||
[Nr. 8 Shellshock](#_Toc536021461)<br>
|
||||
[Nr. 9 Tunneling M1](#_Toc536021462)<br>
|
||||
[Nr. 10 Tunneling M2](#_Toc536021463)<br>
|
||||
[Nr. 11 SSH key steal](#_Toc526517190)<br>
|
||||
|
@ -21,13 +18,8 @@ This document describes Infection Monkey’s test network, how to deploy and use
|
|||
[Nr. 15 Mimikatz](#_Toc536021468)<br>
|
||||
[Nr. 16 MsSQL](#_Toc536021469)<br>
|
||||
[Nr. 17 Upgrader](#_Toc536021470)<br>
|
||||
[Nr. 18 WebLogic](#_Toc526517180)<br>
|
||||
[Nr. 19 WebLogic](#_Toc526517181)<br>
|
||||
[Nr. 20 SMB](#_Toc536021473)<br>
|
||||
[Nr. 21 Scan](#_Toc526517196)<br>
|
||||
[Nr. 22 Scan](#_Toc526517197)<br>
|
||||
[Nr. 23 Struts2](#_Toc536021476)<br>
|
||||
[Nr. 24 Struts2](#_Toc536021477)<br>
|
||||
[Nr. 25 Zerologon](#_Toc536021478)<br>
|
||||
[Nr. 3-45 Powershell](#_Toc536021479)<br>
|
||||
[Nr. 3-46 Powershell](#_Toc536021480)<br>
|
||||
|
@ -252,112 +244,6 @@ Update all requirements using deployment script:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc526517184" class="anchor"></span>Nr. <strong>4</strong> Elastic</p>
|
||||
<p>(10.2.2.4)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 16.04.05 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p><a href="https://www.elastic.co/downloads/past-releases/elasticsearch-1-4-2">Elastic 1.4.2</a></p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>9200</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Scan results:</td>
|
||||
<td>Machine exploited using Elastic exploiter</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td><a href="https://www.elastic.co/guide/en/elasticsearch/reference/1.4/_index_and_query_a_document.html">Quick</a> tutorial on how to add entries (was useful when setting up).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc526517185" class="anchor"></span>Nr. <strong>5</strong> Elastic</p>
|
||||
<p>(10.2.2.5)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows 10 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p><a href="https://www.elastic.co/downloads/past-releases/elasticsearch-1-4-2">Elastic 1.4.2</a></p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>9200</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Scan results:</td>
|
||||
<td>Machine exploited using Elastic exploiter</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td><a href="https://www.elastic.co/guide/en/elasticsearch/reference/1.4/_index_and_query_a_document.html">Quick</a> tutorial on how to add entries (was useful when setting up).</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021461" class="anchor"></span>Nr. <strong>8</strong> Shellshock</p>
|
||||
<p>(10.2.2.8)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 12.04 LTS x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>Apache2, bash 4.2.</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>80</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Scan results:</td>
|
||||
<td>Machine exploited using Shellshock exploiter</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Notes:</td>
|
||||
<td>Vulnerable app is under /cgi-bin/test.cgi</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
|
@ -744,116 +630,6 @@ Update all requirements using deployment script:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc526517180" class="anchor"></span>Nr. <strong>18</strong> WebLogic</p>
|
||||
<p>(10.2.2.18)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 16.04.05 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p><a href="https://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html">Oracle WebLogic server 12.2.1.2</a></p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>7001</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Admin domain credentials:</td>
|
||||
<td>weblogic : B74Ot0c4</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc526517181" class="anchor"></span>Nr. <strong>19</strong> WebLogic</p>
|
||||
<p>(10.2.2.19)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows 10 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p><a href="https://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html">Oracle WebLogic server 12.2.1.2</a></p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>7001</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Admin servers credentials:</td>
|
||||
<td>weblogic : =ThS2d=m(`B</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021473" class="anchor"></span>Nr. <strong>20</strong> SMB</p>
|
||||
<p>(10.2.2.20)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows 10 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default service’s port:</td>
|
||||
<td>445</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Root password:</td>
|
||||
<td>YbS,<tpS.2av</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Server’s config:</td>
|
||||
<td><a href="https://social.technet.microsoft.com/Forums/windows/en-US/8160d62b-0f5d-48a3-9fe9-5cd319837917/how-te-reenable-smb1-in-windows1o?forum=win10itprogeneral">SMB</a> turned on</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
|
@ -922,74 +698,6 @@ Update all requirements using deployment script:<br>
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021476" class="anchor"></span>Nr. <strong>23</strong> Struts2</p>
|
||||
<p>(10.2.2.23)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Ubuntu 16.04.05 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p>struts2 2.3.15.1,</p>
|
||||
<p>tomcat 9.0.0.M9</p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8080</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th><p><span id="_Toc536021477" class="anchor"></span>Nr. <strong>24</strong> Struts2</p>
|
||||
<p>(10.2.2.24)</p></th>
|
||||
<th>(Vulnerable)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>OS:</td>
|
||||
<td><strong>Windows 10 x64</strong></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Software:</td>
|
||||
<td><p>JDK,</p>
|
||||
<p>struts2 2.3.15.1,</p>
|
||||
<p>tomcat 9.0.0.M9</p></td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Default server’s port:</td>
|
||||
<td>8080</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>Server’s config:</td>
|
||||
<td>Default</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Notes:</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
|
@ -1063,7 +771,9 @@ Accessibale through Island using m0nk3y-user.</td>
|
|||
<tr class="even">
|
||||
<td>Notes:</td>
|
||||
<td>User: m0nk3y, Password: nPj8rbc3<br>
|
||||
Accessiable through cached credentials (Windows Island)</td>
|
||||
Accessible using the same m0nk3y user from island, in other words powershell exploiter can exploit
|
||||
this machine without credentials as long as the user running the agent is the same on both
|
||||
machines</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -7,19 +7,6 @@ data "google_compute_image" "hadoop-3" {
|
|||
name = "hadoop-3"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "elastic-4" {
|
||||
name = "elastic-4"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "elastic-5" {
|
||||
name = "elastic-5"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
|
||||
data "google_compute_image" "shellshock-8" {
|
||||
name = "shellshock-8"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "tunneling-9" {
|
||||
name = "tunneling-9"
|
||||
project = local.monkeyzoo_project
|
||||
|
@ -96,18 +83,6 @@ data "google_compute_image" "log4j-logstash-56" {
|
|||
name = "log4j-logstash-56"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "weblogic-18" {
|
||||
name = "weblogic-18"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "weblogic-19" {
|
||||
name = "weblogic-19"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "smb-20" {
|
||||
name = "smb-20"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "scan-21" {
|
||||
name = "scan-21"
|
||||
project = local.monkeyzoo_project
|
||||
|
@ -116,22 +91,10 @@ data "google_compute_image" "scan-22" {
|
|||
name = "scan-22"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "struts2-23" {
|
||||
name = "struts2-23"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "struts2-24" {
|
||||
name = "struts2-24"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "zerologon-25" {
|
||||
name = "zerologon-25"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "drupal-28" {
|
||||
name = "drupal-28"
|
||||
project = local.monkeyzoo_project
|
||||
}
|
||||
data "google_compute_image" "island-linux-250" {
|
||||
name = "island-linux-250"
|
||||
project = local.monkeyzoo_project
|
||||
|
|
|
@ -76,51 +76,6 @@ resource "google_compute_instance_from_template" "hadoop-3" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "elastic-4" {
|
||||
name = "${local.resource_prefix}elastic-4"
|
||||
source_instance_template = local.default_ubuntu
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.elastic-4.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.4"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "elastic-5" {
|
||||
name = "${local.resource_prefix}elastic-5"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.elastic-5.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.5"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "shellshock-8" {
|
||||
name = "${local.resource_prefix}shellshock-8"
|
||||
source_instance_template = local.default_ubuntu
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.shellshock-8.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.8"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "tunneling-9" {
|
||||
name = "${local.resource_prefix}tunneling-9"
|
||||
source_instance_template = local.default_ubuntu
|
||||
|
@ -445,71 +400,6 @@ resource "google_compute_instance_from_template" "log4j-logstash-56" {
|
|||
}
|
||||
}
|
||||
|
||||
/* We need to alter monkey's behavior for this to upload 32-bit monkey instead of 64-bit (not yet developed)
|
||||
resource "google_compute_instance_from_template" "upgrader-17" {
|
||||
name = "${local.resource_prefix}upgrader-17"
|
||||
source_instance_template = "${local.default_windows}"
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = "${data.google_compute_image.upgrader-17.self_link}"
|
||||
}
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.17"
|
||||
access_config {
|
||||
// Cheaper, non-premium routing
|
||||
network_tier = "STANDARD"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
resource "google_compute_instance_from_template" "weblogic-18" {
|
||||
name = "${local.resource_prefix}weblogic-18"
|
||||
source_instance_template = local.default_ubuntu
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.weblogic-18.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.18"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "weblogic-19" {
|
||||
name = "${local.resource_prefix}weblogic-19"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.weblogic-19.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.19"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "smb-20" {
|
||||
name = "${local.resource_prefix}smb-20"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.smb-20.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.20"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "scan-21" {
|
||||
name = "${local.resource_prefix}scan-21"
|
||||
source_instance_template = local.default_ubuntu
|
||||
|
@ -540,36 +430,6 @@ resource "google_compute_instance_from_template" "scan-22" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "struts2-23" {
|
||||
name = "${local.resource_prefix}struts2-23"
|
||||
source_instance_template = local.default_ubuntu
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.struts2-23.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.23"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "struts2-24" {
|
||||
name = "${local.resource_prefix}struts2-24"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.struts2-24.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.24"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "zerologon-25" {
|
||||
name = "${local.resource_prefix}zerologon-25"
|
||||
source_instance_template = local.default_windows
|
||||
|
@ -585,21 +445,6 @@ resource "google_compute_instance_from_template" "zerologon-25" {
|
|||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "drupal-28" {
|
||||
name = "${local.resource_prefix}drupal-28"
|
||||
source_instance_template = local.default_windows
|
||||
boot_disk{
|
||||
initialize_params {
|
||||
image = data.google_compute_image.drupal-28.self_link
|
||||
}
|
||||
auto_delete = true
|
||||
}
|
||||
network_interface {
|
||||
subnetwork="${local.resource_prefix}monkeyzoo-main"
|
||||
network_ip="10.2.2.28"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_from_template" "island-linux-250" {
|
||||
name = "${local.resource_prefix}island-linux-250"
|
||||
machine_type = "n1-standard-2"
|
||||
|
|
|
@ -12,6 +12,8 @@ ACCOUNT_ID_KEY = "accountId"
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
AWS_TIMEOUT = 2
|
||||
|
||||
|
||||
class AwsInstance(CloudInstance):
|
||||
"""
|
||||
|
@ -28,12 +30,14 @@ class AwsInstance(CloudInstance):
|
|||
|
||||
try:
|
||||
response = requests.get(
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/instance-id", timeout=2
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/instance-id",
|
||||
timeout=AWS_TIMEOUT,
|
||||
)
|
||||
self.instance_id = response.text if response else None
|
||||
self.region = self._parse_region(
|
||||
requests.get(
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/placement/availability-zone"
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "meta-data/placement/availability-zone",
|
||||
timeout=AWS_TIMEOUT,
|
||||
).text
|
||||
)
|
||||
except (requests.RequestException, IOError) as e:
|
||||
|
@ -42,7 +46,8 @@ class AwsInstance(CloudInstance):
|
|||
try:
|
||||
self.account_id = self._extract_account_id(
|
||||
requests.get(
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "dynamic/instance-identity/document", timeout=2
|
||||
AWS_LATEST_METADATA_URI_PREFIX + "dynamic/instance-identity/document",
|
||||
timeout=AWS_TIMEOUT,
|
||||
).text
|
||||
)
|
||||
except (requests.RequestException, json.decoder.JSONDecodeError, IOError) as e:
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class CloudProviders(Enum):
|
||||
AWS = "aws"
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
from common.cloud.aws.aws_service import AwsService
|
||||
from common.cmd.aws.aws_cmd_result import AwsCmdResult
|
||||
|
@ -20,6 +21,7 @@ class AwsCmdRunner(CmdRunner):
|
|||
self.ssm = AwsService.get_client("ssm", region)
|
||||
|
||||
def query_command(self, command_id):
|
||||
time.sleep(2)
|
||||
return self.ssm.get_command_invocation(CommandId=command_id, InstanceId=self.instance_id)
|
||||
|
||||
def get_command_result(self, command_info):
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
T1216_PBA_FILE_DOWNLOAD_PATH = "/api/t1216-pba/download"
|
|
@ -0,0 +1,2 @@
|
|||
MIMIKATZ_COLLECTOR = "MimikatzCollector"
|
||||
SSH_COLLECTOR = "SSHCollector"
|
|
@ -0,0 +1,9 @@
|
|||
from enum import Enum, auto
|
||||
|
||||
|
||||
class CredentialComponentType(Enum):
|
||||
USERNAME = auto()
|
||||
PASSWORD = auto()
|
||||
NT_HASH = auto()
|
||||
LM_HASH = auto()
|
||||
SSH_KEYPAIR = auto()
|
|
@ -9,3 +9,4 @@ POST_BREACH_TIMESTOMPING = "Modify files' timestamps"
|
|||
POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC = "Signed script proxy execution"
|
||||
POST_BREACH_ACCOUNT_DISCOVERY = "Account discovery"
|
||||
POST_BREACH_CLEAR_CMD_HISTORY = "Clear command history"
|
||||
POST_BREACH_PROCESS_LIST_COLLECTION = "Collect running processes"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
AWS_COLLECTOR = "AwsCollector"
|
||||
PROCESS_LIST_COLLECTOR = "ProcessListCollector"
|
||||
MIMIKATZ_COLLECTOR = "MimikatzCollector"
|
|
@ -1,11 +1,11 @@
|
|||
class TelemCategoryEnum:
|
||||
ATTACK = "attack"
|
||||
AWS_INFO = "aws_info"
|
||||
CREDENTIALS = "credentials"
|
||||
EXPLOIT = "exploit"
|
||||
FILE_ENCRYPTION = "file_encryption"
|
||||
POST_BREACH = "post_breach"
|
||||
SCAN = "scan"
|
||||
SCOUTSUITE = "scoutsuite"
|
||||
STATE = "state"
|
||||
SYSTEM_INFO = "system_info"
|
||||
TRACE = "trace"
|
||||
TUNNEL = "tunnel"
|
||||
ATTACK = "attack"
|
||||
FILE_ENCRYPTION = "file_encryption"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
SHORT_REQUEST_TIMEOUT = 2.5 # Seconds. Use where we expect timeout.
|
||||
SHORT_REQUEST_TIMEOUT = 2.5 # Seconds. Use where we expect timeout and for small data transactions.
|
||||
MEDIUM_REQUEST_TIMEOUT = 5 # Seconds. Use where we don't expect timeout.
|
||||
LONG_REQUEST_TIMEOUT = 15 # Seconds. Use where we don't expect timeout and operate heavy data.
|
||||
CONNECTION_TIMEOUT = 3 # Seconds. Use for TCP, SSH and other connections that shouldn't take long.
|
||||
|
|
|
@ -41,13 +41,6 @@ TEST_MALICIOUS_ACTIVITY_TIMELINE = "malicious_activity_timeline"
|
|||
TEST_SEGMENTATION = "segmentation"
|
||||
TEST_TUNNELING = "tunneling"
|
||||
TEST_COMMUNICATE_AS_BACKDOOR_USER = "communicate_as_backdoor_user"
|
||||
TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES = "scoutsuite_permissive_firewall_rules"
|
||||
TEST_SCOUTSUITE_UNENCRYPTED_DATA = "scoutsuite_unencrypted_data"
|
||||
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION = "scoutsuite_data_loss_prevention"
|
||||
TEST_SCOUTSUITE_SECURE_AUTHENTICATION = "scoutsuite_secure_authentication"
|
||||
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES = "scoutsuite_unrestrictive_policies"
|
||||
TEST_SCOUTSUITE_LOGGING = "scoutsuite_logging"
|
||||
TEST_SCOUTSUITE_SERVICE_SECURITY = "scoutsuite_service_security"
|
||||
|
||||
TESTS = (
|
||||
TEST_SEGMENTATION,
|
||||
|
@ -59,13 +52,6 @@ TESTS = (
|
|||
TEST_DATA_ENDPOINT_ELASTIC,
|
||||
TEST_TUNNELING,
|
||||
TEST_COMMUNICATE_AS_BACKDOOR_USER,
|
||||
TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES,
|
||||
TEST_SCOUTSUITE_UNENCRYPTED_DATA,
|
||||
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION,
|
||||
TEST_SCOUTSUITE_SECURE_AUTHENTICATION,
|
||||
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES,
|
||||
TEST_SCOUTSUITE_LOGGING,
|
||||
TEST_SCOUTSUITE_SERVICE_SECURITY,
|
||||
)
|
||||
|
||||
PRINCIPLE_DATA_CONFIDENTIALITY = "data_transit"
|
||||
|
@ -219,77 +205,6 @@ TESTS_MAP = {
|
|||
PILLARS_KEY: [PEOPLE, NETWORKS, VISIBILITY_ANALYTICS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_PERMISSIVE_FIREWALL_RULES: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite assessed cloud firewall rules and settings.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found overly permissive firewall rules.",
|
||||
STATUS_PASSED: "ScoutSuite found no problems with cloud firewall rules.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_RESTRICTIVE_NETWORK_POLICIES,
|
||||
PILLARS_KEY: [NETWORKS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_UNENCRYPTED_DATA: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for resources containing " "unencrypted data.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found resources with unencrypted data.",
|
||||
STATUS_PASSED: "ScoutSuite found no resources with unencrypted data.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_DATA_CONFIDENTIALITY,
|
||||
PILLARS_KEY: [DATA],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_DATA_LOSS_PREVENTION: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for resources which are not "
|
||||
"protected against data loss.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found resources not protected against data loss.",
|
||||
STATUS_PASSED: "ScoutSuite found that all resources are secured against data loss.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_DISASTER_RECOVERY,
|
||||
PILLARS_KEY: [DATA],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_SECURE_AUTHENTICATION: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for issues related to users' " "authentication.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found issues related to users' authentication.",
|
||||
STATUS_PASSED: "ScoutSuite found no issues related to users' authentication.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_SECURE_AUTHENTICATION,
|
||||
PILLARS_KEY: [PEOPLE, WORKLOADS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_RESTRICTIVE_POLICIES: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for permissive user access " "policies.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found permissive user access policies.",
|
||||
STATUS_PASSED: "ScoutSuite found no issues related to user access policies.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_USERS_MAC_POLICIES,
|
||||
PILLARS_KEY: [PEOPLE, WORKLOADS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_LOGGING: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for issues, related to logging.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found logging issues.",
|
||||
STATUS_PASSED: "ScoutSuite found no logging issues.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_MONITORING_AND_LOGGING,
|
||||
PILLARS_KEY: [AUTOMATION_ORCHESTRATION, VISIBILITY_ANALYTICS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
TEST_SCOUTSUITE_SERVICE_SECURITY: {
|
||||
TEST_EXPLANATION_KEY: "ScoutSuite searched for service security issues.",
|
||||
FINDING_EXPLANATION_BY_STATUS_KEY: {
|
||||
STATUS_FAILED: "ScoutSuite found service security issues.",
|
||||
STATUS_PASSED: "ScoutSuite found no service security issues.",
|
||||
},
|
||||
PRINCIPLE_KEY: PRINCIPLE_MONITORING_AND_LOGGING,
|
||||
PILLARS_KEY: [DEVICES, NETWORKS],
|
||||
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED],
|
||||
},
|
||||
}
|
||||
|
||||
EVENT_TYPE_MONKEY_NETWORK = "monkey_network"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
AWS_KEYS_PATH = ["internal", "monkey", "aws_keys"]
|
||||
STARTED_ON_ISLAND_PATH = ["internal", "general", "started_on_island"]
|
||||
EXPORT_MONKEY_TELEMS_PATH = ["internal", "testing", "export_monkey_telems"]
|
||||
CURRENT_SERVER_PATH = ["internal", "island_server", "current_server"]
|
||||
SSH_KEYS_PATH = ["internal", "exploits", "exploit_ssh_keys"]
|
||||
|
|
|
@ -4,10 +4,15 @@ import random
|
|||
import socket
|
||||
import struct
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from typing import List, Tuple
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class InvalidNetworkRangeError(Exception):
|
||||
"""Raise when invalid network range is provided"""
|
||||
|
||||
|
||||
class NetworkRange(object, metaclass=ABCMeta):
|
||||
def __init__(self, shuffle=True):
|
||||
self._shuffle = shuffle
|
||||
|
@ -44,23 +49,50 @@ class NetworkRange(object, metaclass=ABCMeta):
|
|||
if not address_str: # Empty string
|
||||
return None
|
||||
address_str = address_str.strip()
|
||||
if address_str.endswith("/32"):
|
||||
address_str = address_str[:-3]
|
||||
if NetworkRange.check_if_range(address_str):
|
||||
return IpRange(ip_range=address_str)
|
||||
if -1 != address_str.find("/"):
|
||||
if "/" in address_str:
|
||||
return CidrRange(cidr_range=address_str)
|
||||
return SingleIpRange(ip_address=address_str)
|
||||
|
||||
@staticmethod
|
||||
def filter_invalid_ranges(ranges: List[str], error_msg: str) -> List[str]:
|
||||
valid_ranges = []
|
||||
for target_range in ranges:
|
||||
try:
|
||||
NetworkRange.validate_range(target_range)
|
||||
except InvalidNetworkRangeError as e:
|
||||
logger.error(f"{error_msg} {e}")
|
||||
continue
|
||||
valid_ranges.append(target_range)
|
||||
return valid_ranges
|
||||
|
||||
@staticmethod
|
||||
def validate_range(address_str: str):
|
||||
try:
|
||||
NetworkRange.get_range_obj(address_str)
|
||||
except (ValueError, OSError) as e:
|
||||
raise InvalidNetworkRangeError(e)
|
||||
|
||||
@staticmethod
|
||||
def check_if_range(address_str):
|
||||
if -1 != address_str.find("-"):
|
||||
ips = address_str.split("-")
|
||||
try:
|
||||
ipaddress.ip_address(ips[0]) and ipaddress.ip_address(ips[1])
|
||||
NetworkRange._range_to_ips(address_str)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _range_to_ips(ip_range: str) -> Tuple[str, str]:
|
||||
ips = ip_range.split("-")
|
||||
ips = [ip.strip() for ip in ips]
|
||||
ips = sorted(ips, key=lambda ip: socket.inet_aton(ip))
|
||||
return ips[0], ips[1]
|
||||
|
||||
@staticmethod
|
||||
def _ip_to_number(address):
|
||||
return struct.unpack(">L", socket.inet_aton(address))[0]
|
||||
|
@ -94,12 +126,7 @@ class IpRange(NetworkRange):
|
|||
def __init__(self, ip_range=None, lower_end_ip=None, higher_end_ip=None, shuffle=True):
|
||||
super(IpRange, self).__init__(shuffle=shuffle)
|
||||
if ip_range is not None:
|
||||
addresses = ip_range.split("-")
|
||||
if len(addresses) != 2:
|
||||
raise ValueError(
|
||||
"Illegal IP range format: %s. Format is 192.168.0.5-192.168.0.20" % ip_range
|
||||
)
|
||||
self._lower_end_ip, self._higher_end_ip = [x.strip() for x in addresses]
|
||||
self._lower_end_ip, self._higher_end_ip = IpRange._range_to_ips(ip_range)
|
||||
elif (lower_end_ip is not None) and (higher_end_ip is not None):
|
||||
self._lower_end_ip = lower_end_ip.strip()
|
||||
self._higher_end_ip = higher_end_ip.strip()
|
||||
|
@ -163,7 +190,10 @@ class SingleIpRange(NetworkRange):
|
|||
:return: A tuple in format (IP, domain_name). Eg. (192.168.55.1, www.google.com)
|
||||
"""
|
||||
# The most common use case is to enter ip/range into "Scan IP/subnet list"
|
||||
domain_name = ""
|
||||
domain_name = None
|
||||
|
||||
if " " in string_:
|
||||
raise ValueError(f'"{string_}" is not a valid IP address or domain name.')
|
||||
|
||||
# Try casting user's input as IP
|
||||
try:
|
||||
|
@ -174,10 +204,9 @@ class SingleIpRange(NetworkRange):
|
|||
ip = socket.gethostbyname(string_)
|
||||
domain_name = string_
|
||||
except socket.error:
|
||||
logger.error(
|
||||
raise ValueError(
|
||||
"Your specified host: {} is not found as a domain name and"
|
||||
" it's not an IP address".format(string_)
|
||||
)
|
||||
return None, string_
|
||||
# If a string_ was entered instead of IP we presume that it was domain name and translate it
|
||||
return ip, domain_name
|
||||
|
|
|
@ -1,22 +1,9 @@
|
|||
import re
|
||||
from urllib.parse import urlparse
|
||||
from typing import Optional, Tuple
|
||||
|
||||
|
||||
def get_host_from_network_location(network_location: str) -> str:
|
||||
"""
|
||||
URL structure is "<scheme>://<net_loc>/<path>;<params>?<query>#<fragment>" (
|
||||
https://tools.ietf.org/html/rfc1808.html)
|
||||
And the net_loc is "<user>:<password>@<host>:<port>" (
|
||||
https://tools.ietf.org/html/rfc1738#section-3.1)
|
||||
:param network_location: server network location
|
||||
:return: host part of the network location
|
||||
"""
|
||||
url = urlparse("http://" + network_location)
|
||||
return str(url.hostname)
|
||||
|
||||
|
||||
def remove_port(url):
|
||||
parsed = urlparse(url)
|
||||
with_port = f"{parsed.scheme}://{parsed.netloc}"
|
||||
without_port = re.sub(":[0-9]+(?=$|/)", "", with_port)
|
||||
return without_port
|
||||
def address_to_ip_port(address: str) -> Tuple[str, Optional[str]]:
|
||||
if ":" in address:
|
||||
ip, port = address.split(":")
|
||||
return ip, port or None
|
||||
else:
|
||||
return address, None
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# abstract, static method decorator
|
||||
# noinspection PyPep8Naming
|
||||
from typing import List
|
||||
|
||||
|
||||
class abstractstatic(staticmethod):
|
||||
|
@ -11,10 +10,3 @@ class abstractstatic(staticmethod):
|
|||
function.__isabstractmethod__ = True
|
||||
|
||||
__isabstractmethod__ = True
|
||||
|
||||
|
||||
def get_value_from_dict(dict_data: dict, path: List[str]):
|
||||
current_data = dict_data
|
||||
for key in path:
|
||||
current_data = current_data[key]
|
||||
return current_data
|
||||
|
|
|
@ -1,58 +1,42 @@
|
|||
class ExploitingVulnerableMachineError(Exception):
|
||||
""" Raise when exploiter failed, but machine is vulnerable """
|
||||
|
||||
|
||||
class FailedExploitationError(Exception):
|
||||
""" Raise when exploiter fails instead of returning False """
|
||||
"""Raise when exploiter fails instead of returning False"""
|
||||
|
||||
|
||||
class InvalidRegistrationCredentialsError(Exception):
|
||||
""" Raise when server config file changed and island needs to restart """
|
||||
"""Raise when server config file changed and island needs to restart"""
|
||||
|
||||
|
||||
class AlreadyRegisteredError(Exception):
|
||||
""" Raise to indicate the reason why registration is not required """
|
||||
"""Raise to indicate the reason why registration is not required"""
|
||||
|
||||
|
||||
class UnknownUserError(Exception):
|
||||
""" Raise to indicate that authentication failed """
|
||||
"""Raise to indicate that authentication failed"""
|
||||
|
||||
|
||||
class IncorrectCredentialsError(Exception):
|
||||
""" Raise to indicate that authentication failed """
|
||||
|
||||
|
||||
class RulePathCreatorNotFound(Exception):
|
||||
""" Raise to indicate that ScoutSuite rule doesn't have a path creator"""
|
||||
|
||||
|
||||
class InvalidAWSKeys(Exception):
|
||||
""" Raise to indicate that AWS API keys are invalid"""
|
||||
"""Raise to indicate that authentication failed"""
|
||||
|
||||
|
||||
class NoInternetError(Exception):
|
||||
""" Raise to indicate problems caused when no internet connection is present"""
|
||||
|
||||
|
||||
class ScoutSuiteScanError(Exception):
|
||||
""" Raise to indicate problems ScoutSuite encountered during scanning"""
|
||||
"""Raise to indicate problems caused when no internet connection is present"""
|
||||
|
||||
|
||||
class UnknownFindingError(Exception):
|
||||
""" Raise when provided finding is of unknown type"""
|
||||
"""Raise when provided finding is of unknown type"""
|
||||
|
||||
|
||||
class VersionServerConnectionError(Exception):
|
||||
""" Raise to indicate that connection to version update server failed """
|
||||
"""Raise to indicate that connection to version update server failed"""
|
||||
|
||||
|
||||
class FindingWithoutDetailsError(Exception):
|
||||
""" Raise when pulling events for a finding, but get none """
|
||||
"""Raise when pulling events for a finding, but get none"""
|
||||
|
||||
|
||||
class DomainControllerNameFetchError(FailedExploitationError):
|
||||
""" Raise on failed attempt to extract domain controller's name """
|
||||
"""Raise on failed attempt to extract domain controller's name"""
|
||||
|
||||
|
||||
class InvalidConfigurationError(Exception):
|
||||
""" Raise when configuration is invalid """
|
||||
"""Raise when configuration is invalid"""
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class ExploitType(Enum):
|
||||
VULNERABILITY = 1
|
||||
BRUTE_FORCE = 9
|
|
@ -1,30 +0,0 @@
|
|||
# This code is used to obfuscate shellcode
|
||||
# Usage:
|
||||
# shellcode_obfuscator.py [your normal shellcode].
|
||||
|
||||
import sys
|
||||
|
||||
# PyCrypto is deprecated, but we use pycryptodome, which uses the exact same imports
|
||||
from Crypto.Cipher import AES # noqa: DUO133 # nosec: B413
|
||||
|
||||
# We only encrypt payloads to hide them from static analysis
|
||||
# it's OK to have these keys plaintext
|
||||
KEY = b"1234567890123456"
|
||||
NONCE = b"\x93n2\xbc\xf5\x8d:\xc2fP\xabn\x02\xb3\x17f"
|
||||
|
||||
|
||||
# Use this manually to get obfuscated bytes of shellcode
|
||||
def obfuscate(shellcode: bytes) -> bytes:
|
||||
cipher = AES.new(KEY, AES.MODE_EAX, nonce=NONCE)
|
||||
ciphertext, _ = cipher.encrypt_and_digest(shellcode)
|
||||
return ciphertext
|
||||
|
||||
|
||||
def clarify(shellcode: bytes) -> bytes:
|
||||
cipher = AES.new(KEY, AES.MODE_EAX, nonce=NONCE)
|
||||
plaintext = cipher.decrypt(shellcode)
|
||||
return plaintext
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(obfuscate(sys.argv[1].encode()))
|
|
@ -4,35 +4,29 @@ verify_ssl = true
|
|||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
cryptography = "==2.5" # We can't build 32bit ubuntu12 binary with newer versions of cryptography
|
||||
pyinstaller = {git = "git://github.com/guardicore/pyinstaller"}
|
||||
pyinstaller-hooks-contrib = "==2021.1" # Required to build docker with our pyinstaller branch
|
||||
pyinstaller = "==4.9"
|
||||
impacket = ">=0.9"
|
||||
importlib-metadata = "==4.0.1" # Required to build docker with our pyinstaller branch
|
||||
ipaddress = ">=1.0.23"
|
||||
netifaces = ">=0.10.9"
|
||||
odict = "==1.7.0"
|
||||
paramiko = ">=2.7.1"
|
||||
psutil = ">=5.7.0"
|
||||
pymssql = "==2.1.5"
|
||||
pypykatz = "==0.3.12"
|
||||
pypykatz = "==0.5.2"
|
||||
requests = ">=2.24"
|
||||
urllib3 = "==1.26.5"
|
||||
WMI = {version = "==1.5.1", sys_platform = "== 'win32'"}
|
||||
ScoutSuite = {git = "git://github.com/guardicode/ScoutSuite"}
|
||||
pyopenssl = "==19.0.0" # We can't build 32bit ubuntu12 binary with newer versions of pyopenssl
|
||||
pypsrp = "*"
|
||||
typing-extensions = "*" # Allows us to use 3.9 typing features on 3.7 project
|
||||
pycryptodome = "*" # Used in common/utils/shellcode_obfuscator.py
|
||||
altgraph = "*" # Required for pyinstaller branch, without it agents fail to build
|
||||
pysmb = "*"
|
||||
"WinSys-3.x" = "*"
|
||||
ldaptor = "*"
|
||||
pywin32-ctypes = {version = "*", sys_platform = "== 'win32'"} # Pyinstaller requirement on windows
|
||||
pywin32 = {version = "*", sys_platform = "== 'win32'"} # Lock file is not created with sys_platform win32 requirement if not explicitly specified
|
||||
pefile = {version = "*", sys_platform = "== 'win32'"} # Pyinstaller requirement on windows
|
||||
paramiko = {editable = true, ref = "2.10.3.dev1", git = "https://github.com/VakarisZ/paramiko.git"}
|
||||
|
||||
[dev-packages]
|
||||
ldap3 = "*"
|
||||
pywin32-ctypes = {version = "*", sys_platform = "== 'win32'"}
|
||||
pefile = {version = "*", sys_platform = "== 'win32'"}
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "1495c89a3acf6a14a0ef9a00bf5660181b1c4bc4ff8e4f470f90cab3da424f70"
|
||||
"sha256": "c1c28510b728242624129b39bd9ace9ba2629061bf64226cb43f1f857fc87212"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -16,6 +16,14 @@
|
|||
]
|
||||
},
|
||||
"default": {
|
||||
"aiosmb": {
|
||||
"hashes": [
|
||||
"sha256:0afa901093f0ad91d0b8421dec66c80bd2e9cb237a8da405984413a5d7475398",
|
||||
"sha256:0e98390ba00fdc4190e698f184dfcf72b02b592cdfe9274e03cc7316ac4ee368"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.3.8"
|
||||
},
|
||||
"aiowinreg": {
|
||||
"hashes": [
|
||||
"sha256:6cd7f64ef002a7c6d7c27310db578fbc8992eeaca0936ebc56283d70c54573f2",
|
||||
|
@ -29,30 +37,22 @@
|
|||
"sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857",
|
||||
"sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.17.2"
|
||||
},
|
||||
"asn1crypto": {
|
||||
"hashes": [
|
||||
"sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8",
|
||||
"sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c"
|
||||
"sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c",
|
||||
"sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"
|
||||
],
|
||||
"version": "==1.4.0"
|
||||
},
|
||||
"asyncio-throttle": {
|
||||
"hashes": [
|
||||
"sha256:a01a56f3671e961253cf262918f3e0741e222fc50d57d981ba5c801f284eccfe"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.1.1"
|
||||
"version": "==1.5.1"
|
||||
},
|
||||
"asysocks": {
|
||||
"hashes": [
|
||||
"sha256:5ec0582252b0085d9337d13c6b03ab7fd062e487070667f9140e6972bd9db256",
|
||||
"sha256:b97ac905cd4ca1e7a8e7c295f9cb22ced5dfd3f17e888e71cbf05a1d67a4d393"
|
||||
"sha256:23d5fcfae71a75826c3ed787bd9b1bc3b189ec37658961bce83c9e99455e354c",
|
||||
"sha256:731eda25d41783c5243153d3cb4f9357fef337c7317135488afab9ecd6b7f1a1"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.1.6"
|
||||
"version": "==0.1.7"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
|
@ -85,22 +85,6 @@
|
|||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"boto3": {
|
||||
"hashes": [
|
||||
"sha256:26f18ca7411615f33d8d1bf60cc8efe5b331a57b3013d5f8f3587cd5350c27cb",
|
||||
"sha256:4470f64e4af609ff678055338c96a6f7cbe601d1fb06a4ea7dc8d9223c2e527a"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.20.44"
|
||||
},
|
||||
"botocore": {
|
||||
"hashes": [
|
||||
"sha256:11483a493de4a76ef218d8cd3980c63550d006a0d082c10d53c0954184ca542a",
|
||||
"sha256:8e5317f84fc1118bff58fa6fa79a9b62083e75a2a9c62feb3ea73694c550b99d"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.23.44"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
|
||||
|
@ -173,59 +157,28 @@
|
|||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd",
|
||||
"sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"
|
||||
"sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597",
|
||||
"sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"
|
||||
],
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==2.0.10"
|
||||
},
|
||||
"cheroot": {
|
||||
"hashes": [
|
||||
"sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25",
|
||||
"sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==8.6.0"
|
||||
},
|
||||
"cherrypy": {
|
||||
"hashes": [
|
||||
"sha256:55659e6f012d374898d6d9d581e17cc1477b6a14710218e64f187b9227bea038",
|
||||
"sha256:f33e87286e7b3e309e04e7225d8e49382d9d7773e6092241d7f613893c563495"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==18.6.1"
|
||||
},
|
||||
"cherrypy-cors": {
|
||||
"hashes": [
|
||||
"sha256:eb512e20fa9e478abd1868b1417814a4e9240ed0c403472a2c624460e49ab0d5",
|
||||
"sha256:f7fb75f6e617ce29c9ec3fdd8b1ff6ec64fec2c56371182525e22bcf4c180513"
|
||||
],
|
||||
"markers": "python_version >= '2.7'",
|
||||
"version": "==1.6"
|
||||
"version": "==2.0.12"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3",
|
||||
"sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"
|
||||
"sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e",
|
||||
"sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.0.3"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.2"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
|
||||
"sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"markers": "platform_system == 'Windows' and platform_system == 'Windows'",
|
||||
"version": "==0.4.4"
|
||||
},
|
||||
"coloredlogs": {
|
||||
"hashes": [
|
||||
"sha256:34fad2e342d5a559c31b6c889e8d14f97cb62c47d9a2ae7b5ed14ea10a79eff8",
|
||||
"sha256:b869a2dda3fa88154b9dd850e27828d8755bfab5a838a1c97fbc850c6e377c36"
|
||||
],
|
||||
"version": "==10.0"
|
||||
},
|
||||
"constantly": {
|
||||
"hashes": [
|
||||
"sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35",
|
||||
|
@ -235,44 +188,45 @@
|
|||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:05b3ded5e88747d28ee3ef493f2b92cbb947c1e45cf98cfef22e6d38bb67d4af",
|
||||
"sha256:06826e7f72d1770e186e9c90e76b4f84d90cdb917b47ff88d8dc59a7b10e2b1e",
|
||||
"sha256:08b753df3672b7066e74376f42ce8fc4683e4fd1358d34c80f502e939ee944d2",
|
||||
"sha256:2cd29bd1911782baaee890544c653bb03ec7d95ebeb144d714b0f5c33deb55c7",
|
||||
"sha256:31e5637e9036d966824edaa91bf0aa39dc6f525a1c599f39fd5c50340264e079",
|
||||
"sha256:42fad67d7072216a49e34f923d8cbda9edacbf6633b19a79655e88a1b4857063",
|
||||
"sha256:4946b67235b9d2ea7d31307be9d5ad5959d6c4a8f98f900157b47abddf698401",
|
||||
"sha256:522fdb2809603ee97a4d0ef2f8d617bc791eb483313ba307cb9c0a773e5e5695",
|
||||
"sha256:6f841c7272645dd7c65b07b7108adfa8af0aaea57f27b7f59e01d41f75444c85",
|
||||
"sha256:7d335e35306af5b9bc0560ca39f740dfc8def72749645e193dd35be11fb323b3",
|
||||
"sha256:8504661ffe324837f5c4607347eeee4cf0fcad689163c6e9c8d3b18cf1f4a4ad",
|
||||
"sha256:9260b201ce584d7825d900c88700aa0bd6b40d4ebac7b213857bd2babee9dbca",
|
||||
"sha256:9a30384cc402eac099210ab9b8801b2ae21e591831253883decdb4513b77a3cd",
|
||||
"sha256:9e29af877c29338f0cab5f049ccc8bd3ead289a557f144376c4fbc7d1b98914f",
|
||||
"sha256:ab50da871bc109b2d9389259aac269dd1b7c7413ee02d06fe4e486ed26882159",
|
||||
"sha256:b13c80b877e73bcb6f012813c6f4a9334fcf4b0e96681c5a15dac578f2eedfa0",
|
||||
"sha256:bfe66b577a7118e05b04141f0f1ed0959552d45672aa7ecb3d91e319d846001e",
|
||||
"sha256:e091bd424567efa4b9d94287a952597c05d22155a13716bf5f9f746b9dc906d3",
|
||||
"sha256:fa2b38c8519c5a3aa6e2b4e1cf1a549b54acda6adb25397ff542068e73d1ed00"
|
||||
"sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b",
|
||||
"sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51",
|
||||
"sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7",
|
||||
"sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d",
|
||||
"sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6",
|
||||
"sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29",
|
||||
"sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9",
|
||||
"sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf",
|
||||
"sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815",
|
||||
"sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf",
|
||||
"sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85",
|
||||
"sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77",
|
||||
"sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86",
|
||||
"sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb",
|
||||
"sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e",
|
||||
"sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0",
|
||||
"sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3",
|
||||
"sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84",
|
||||
"sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2",
|
||||
"sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.5"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==36.0.2"
|
||||
},
|
||||
"dnspython": {
|
||||
"hashes": [
|
||||
"sha256:081649da27ced5e75709a1ee542136eaba9842a0fe4c03da4fb0a3d3ed1f3c44",
|
||||
"sha256:e79351e032d0b606b98d38a4b0e6e2275b31a5b85c873e587cc11b73aca026d6"
|
||||
"sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e",
|
||||
"sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f"
|
||||
],
|
||||
"markers": "python_version >= '3.6' and python_version < '4.0'",
|
||||
"version": "==2.2.0"
|
||||
"markers": "python_version >= '3.6' and python_version < '4'",
|
||||
"version": "==2.2.1"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2",
|
||||
"sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"
|
||||
"sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264",
|
||||
"sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.2"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"future": {
|
||||
"hashes": [
|
||||
|
@ -281,20 +235,6 @@
|
|||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.18.2"
|
||||
},
|
||||
"httpagentparser": {
|
||||
"hashes": [
|
||||
"sha256:a190dfdc5e63b2f1c87729424b19cbc49263d6a1fb585a16ac1c9d9ce127a4bf"
|
||||
],
|
||||
"version": "==1.9.2"
|
||||
},
|
||||
"humanfriendly": {
|
||||
"hashes": [
|
||||
"sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477",
|
||||
"sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==10.0"
|
||||
},
|
||||
"hyperlink": {
|
||||
"hashes": [
|
||||
"sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
|
||||
|
@ -319,19 +259,11 @@
|
|||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:8c501196e49fb9df5df43833bdb1e4328f64847763ec8a50703148b73784d581",
|
||||
"sha256:d7eb1dea6d6a6086f8be21784cc9e3bcfa55872b52309bc5fad53a8ea444465d"
|
||||
"sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6",
|
||||
"sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.1"
|
||||
},
|
||||
"importlib-resources": {
|
||||
"hashes": [
|
||||
"sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45",
|
||||
"sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b"
|
||||
],
|
||||
"markers": "python_version < '3.9'",
|
||||
"version": "==5.4.0"
|
||||
"markers": "python_version < '3.10'",
|
||||
"version": "==4.11.3"
|
||||
},
|
||||
"incremental": {
|
||||
"hashes": [
|
||||
|
@ -350,67 +282,19 @@
|
|||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c",
|
||||
"sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"jaraco.classes": {
|
||||
"hashes": [
|
||||
"sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d",
|
||||
"sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.2.1"
|
||||
},
|
||||
"jaraco.collections": {
|
||||
"hashes": [
|
||||
"sha256:b04f00bd4b3c4fc4ba5fe1baf8042c0efd192b13e386830ea23fff77bb69dc88",
|
||||
"sha256:ef7c308d6d7cadfb16b32c7e414d628151ab02b57a5702b9d9a293148c035e70"
|
||||
"sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44",
|
||||
"sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.1"
|
||||
},
|
||||
"jaraco.context": {
|
||||
"hashes": [
|
||||
"sha256:17b909da2fb37ad237ca7ff9523977f8665a47a25b90aec6a99a3e0959c86141",
|
||||
"sha256:f0d4d82ffbbbff680384eba48a32a3167f12a91a30a7db56fd97b87e73a87241"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.1.1"
|
||||
},
|
||||
"jaraco.functools": {
|
||||
"hashes": [
|
||||
"sha256:141f95c490a18eb8aab86caf7a2728f02f604988a26dc36652e3d9fa9e4c49fa",
|
||||
"sha256:31e0e93d1027592b7b0bec6ad468db850338981ebee76ba5e212e235f4c7dda0"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.0"
|
||||
},
|
||||
"jaraco.text": {
|
||||
"hashes": [
|
||||
"sha256:17b43aa0bd46e97c368ccd8a4c8fef2719ca121b6d39ce4be9d9e0143832479a",
|
||||
"sha256:a7f9cc1b44a5f3096a216cbd130b650c7a6b2c9f8005b000ae97f329239a7c00"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.7.0"
|
||||
"version": "==2.1.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8",
|
||||
"sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"
|
||||
"sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119",
|
||||
"sha256:640bed4bb501cbd17194b3cace1dc2126f5b619cf068a726b98192a0fde74ae9"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.0.3"
|
||||
},
|
||||
"jmespath": {
|
||||
"hashes": [
|
||||
"sha256:b85d0567b8666149a93172712e68920734333c0ce7e89b78b3e987f71e5ed4f9",
|
||||
"sha256:cdf6525904cc597730141d61b36f2e4b8ecc257c420fa2f4549bac2c2d0cb72f"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.10.0"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.1"
|
||||
},
|
||||
"ldap3": {
|
||||
"hashes": [
|
||||
|
@ -440,78 +324,49 @@
|
|||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298",
|
||||
"sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64",
|
||||
"sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b",
|
||||
"sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194",
|
||||
"sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567",
|
||||
"sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff",
|
||||
"sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724",
|
||||
"sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74",
|
||||
"sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646",
|
||||
"sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35",
|
||||
"sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6",
|
||||
"sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a",
|
||||
"sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6",
|
||||
"sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad",
|
||||
"sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26",
|
||||
"sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38",
|
||||
"sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac",
|
||||
"sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7",
|
||||
"sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6",
|
||||
"sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047",
|
||||
"sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75",
|
||||
"sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f",
|
||||
"sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b",
|
||||
"sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135",
|
||||
"sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8",
|
||||
"sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a",
|
||||
"sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a",
|
||||
"sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1",
|
||||
"sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9",
|
||||
"sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864",
|
||||
"sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914",
|
||||
"sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee",
|
||||
"sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f",
|
||||
"sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18",
|
||||
"sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8",
|
||||
"sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2",
|
||||
"sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d",
|
||||
"sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b",
|
||||
"sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b",
|
||||
"sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86",
|
||||
"sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6",
|
||||
"sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f",
|
||||
"sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb",
|
||||
"sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833",
|
||||
"sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28",
|
||||
"sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e",
|
||||
"sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415",
|
||||
"sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902",
|
||||
"sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f",
|
||||
"sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d",
|
||||
"sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9",
|
||||
"sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d",
|
||||
"sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145",
|
||||
"sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066",
|
||||
"sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c",
|
||||
"sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1",
|
||||
"sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a",
|
||||
"sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207",
|
||||
"sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f",
|
||||
"sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53",
|
||||
"sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd",
|
||||
"sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134",
|
||||
"sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85",
|
||||
"sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9",
|
||||
"sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5",
|
||||
"sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94",
|
||||
"sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509",
|
||||
"sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51",
|
||||
"sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"
|
||||
"sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
|
||||
"sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
|
||||
"sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
|
||||
"sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
|
||||
"sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
|
||||
"sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
|
||||
"sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
|
||||
"sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
|
||||
"sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
|
||||
"sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
|
||||
"sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
|
||||
"sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
|
||||
"sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
|
||||
"sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
|
||||
"sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
|
||||
"sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
|
||||
"sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
|
||||
"sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
|
||||
"sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
|
||||
"sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
|
||||
"sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
|
||||
"sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
|
||||
"sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
|
||||
"sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
|
||||
"sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
|
||||
"sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
|
||||
"sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
|
||||
"sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
|
||||
"sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
|
||||
"sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
|
||||
"sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
|
||||
"sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
|
||||
"sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
|
||||
"sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
|
||||
"sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
|
||||
"sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
|
||||
"sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
|
||||
"sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
|
||||
"sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
|
||||
"sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.1"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"minidump": {
|
||||
"hashes": [
|
||||
|
@ -523,34 +378,19 @@
|
|||
},
|
||||
"minikerberos": {
|
||||
"hashes": [
|
||||
"sha256:eba89d5c649241a3367839ebd1c0333b9a9e4fe514746e246a6a1f2cb7bde26e",
|
||||
"sha256:f556a6015904147c3302e9038b49f766c975df6aeb1725027cd7fc68ba993864"
|
||||
"sha256:3c383f67ebcf6f28105ed54f623a6a5c677a24e3f0c9ad69ed453f77e569d714",
|
||||
"sha256:789f802263fa1882f701b123f6eec048b45cd731bf1b528870005daf07402047"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.2.16"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:43e6dd9942dffd72661a2c4ef383ad7da1e6a3e968a927ad7a6083ab410a688b",
|
||||
"sha256:7dc6ad46f05f545f900dd59e8dfb4e84a4827b97b3cfecb175ea0c7d247f6064"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==8.12.0"
|
||||
"version": "==0.2.20"
|
||||
},
|
||||
"msldap": {
|
||||
"hashes": [
|
||||
"sha256:37e1b1044792595ca78fc14402baf84922e0a3838b36534ecd5a75cdd81e74ee",
|
||||
"sha256:7d7f96d41ab8174ffa0f2c56780eb3be8b3015009d0e94a4dbd83b9ead5c6181"
|
||||
"sha256:c9e530a5e61a2a4584c3541a1e40787399b9225a4f727ad13ad0b4998bfda03a",
|
||||
"sha256:cc9129f3f8cf4c06f7469cf25f249db55976b922e94a2ac690987b181ff74307"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.3.30"
|
||||
},
|
||||
"netaddr": {
|
||||
"hashes": [
|
||||
"sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac",
|
||||
"sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"
|
||||
],
|
||||
"version": "==0.8.0"
|
||||
"version": "==0.3.38"
|
||||
},
|
||||
"netifaces": {
|
||||
"hashes": [
|
||||
|
@ -597,18 +437,15 @@
|
|||
},
|
||||
"oscrypto": {
|
||||
"hashes": [
|
||||
"sha256:7d2cca6235d89d1af6eb9cfcd4d2c0cb405849868157b2f7b278beb644d48694",
|
||||
"sha256:988087e05b17df8bfcc7c5fac51f54595e46d3e4dffa7b3d15955cf61a633529"
|
||||
"sha256:2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085",
|
||||
"sha256:6f5fef59cb5b3708321db7cca56aed8ad7e662853351e7991fcf60ec606d47a4"
|
||||
],
|
||||
"version": "==1.2.1"
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"paramiko": {
|
||||
"hashes": [
|
||||
"sha256:04097dbd96871691cdb34c13db1883066b8a13a0df2afd4cb0a92221f51c2603",
|
||||
"sha256:944a9e5dbdd413ab6c7951ea46b0ab40713235a9c4c5ca81cfe45c6f14fa677b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.9.2"
|
||||
"editable": true,
|
||||
"git": "https://github.com/VakarisZ/paramiko.git",
|
||||
"ref": "d554bc53b9712e5fbb5e444750ad9d91f8c0b16f"
|
||||
},
|
||||
"passlib": {
|
||||
"hashes": [
|
||||
|
@ -621,31 +458,17 @@
|
|||
"hashes": [
|
||||
"sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"index": "pypi",
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==2021.9.3"
|
||||
},
|
||||
"policyuniverse": {
|
||||
"hashes": [
|
||||
"sha256:116b808554d7ea75efc97b4cb904085546db45934ef315175cb4755c7a4489de",
|
||||
"sha256:7440ac520bb791e0318e3d99f9b0e76b7b2b604e7160f1d8341ded060f9ff1cd"
|
||||
],
|
||||
"version": "==1.4.0.20220110"
|
||||
},
|
||||
"portend": {
|
||||
"hashes": [
|
||||
"sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4",
|
||||
"sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:45f3137a16a7bb5893928f918bfcc36cfe812db49437d087201cd2a78016cbb3",
|
||||
"sha256:c79f8d3fe475116a2daaed1c5c08d4450becbe7b5c1a513d50b6d45248857a67"
|
||||
"sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752",
|
||||
"sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.0.25"
|
||||
"version": "==3.0.29"
|
||||
},
|
||||
"psutil": {
|
||||
"hashes": [
|
||||
|
@ -729,89 +552,63 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.21"
|
||||
},
|
||||
"pycryptodome": {
|
||||
"hashes": [
|
||||
"sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691",
|
||||
"sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6",
|
||||
"sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1",
|
||||
"sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f",
|
||||
"sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90",
|
||||
"sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02",
|
||||
"sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5",
|
||||
"sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1",
|
||||
"sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f",
|
||||
"sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3",
|
||||
"sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732",
|
||||
"sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6",
|
||||
"sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863",
|
||||
"sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f",
|
||||
"sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e",
|
||||
"sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d",
|
||||
"sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4",
|
||||
"sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b",
|
||||
"sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d",
|
||||
"sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2",
|
||||
"sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5",
|
||||
"sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf",
|
||||
"sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3",
|
||||
"sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d",
|
||||
"sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a",
|
||||
"sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873",
|
||||
"sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27",
|
||||
"sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f",
|
||||
"sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5",
|
||||
"sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.13.0"
|
||||
},
|
||||
"pycryptodomex": {
|
||||
"hashes": [
|
||||
"sha256:00e37d478c0f040639ab41a9d5280291ad2b3b5f25b9aad5baa1d5ecb578a3f6",
|
||||
"sha256:04a38a7dc484f5e3152a69e4eab89d9340c2ad3b7c4a27d2ee256e5fb878c469",
|
||||
"sha256:05e0e3b78b7ccc0b7c5f88596d51fdc8533adb91070b93e18cec12ca3b43deb3",
|
||||
"sha256:0ec86fca2114e8c58fe6bfc7e04ee91568a813139dcf4334819aa44876764bcf",
|
||||
"sha256:182962b3612c0d12748fa770f1ef0556ba8ba2c442834450e08acb31d9e6d2ed",
|
||||
"sha256:2f2bcee2ef59597bfcb755eef2c98294094c1c9b64e9b9195cc9e71be83adb92",
|
||||
"sha256:2f7db8d85294c1123e700097af407425fd4c9e6c58b688f391de7053c6a60317",
|
||||
"sha256:3b7656189c259bb2b838559f0a11b533d4d18409ab6d9119c00bae436c3d3e34",
|
||||
"sha256:5a2014598ceb19c34f14815a26536e5cc24167ea4d402f0aec2a52b18960c668",
|
||||
"sha256:63443230247837dd03c5d4028cae5cb2e6793a9ae110e321798bee48a04ff3e9",
|
||||
"sha256:68fb861b41a889c2efdf2795b0d46aa05d4748543bc4e0bca5886c929c7cbdef",
|
||||
"sha256:6b3c06e6d235f475395a7e150f2e562a3e9d749fb40c6d81240596f73809346c",
|
||||
"sha256:6d50723984ba802904618ef5bfe257a0f9644e76821d323f79f27be5adb9ece7",
|
||||
"sha256:7fb188c9a0f69d4f7b607780641ef7aec7f02a8dad689512b17bdf04c96ce6e3",
|
||||
"sha256:7fb9d1ab6a10cfc8c8c7e11f004e01c8a1beff5fd4118370d95110735cc23117",
|
||||
"sha256:80eedc23c4c4d3655c6a7d315a01f0e9d460c7070c5c3af4952937b4f2c0da6f",
|
||||
"sha256:9fa76261100b450e5aca2990ba982e5294ba383f653da041a71b4ac1cbaed1ff",
|
||||
"sha256:b11331510cfd08ec4416f37dc8f072541d7b7240ba924c71288f7218aad36bdf",
|
||||
"sha256:b4240991748ae0f57a0120b8d905b2d9f835fee02968fc11faec929ef6915ee6",
|
||||
"sha256:b7b059517d84c57f25c6fd3b2e03a1b2945df2e585b96109bcd11e56f6c9e610",
|
||||
"sha256:b975ce778ea2c65f399ab889a661e118bb68b85db47d93e0442eb1ba1f554794",
|
||||
"sha256:c87f62de9e167031ad4179efb1fda4012bb6f7363472a61254e4426bda6bcb64",
|
||||
"sha256:ccd301d2e71d243b0fad8c4642116c538d7d405d35b6026cf4dcee463a667a2e",
|
||||
"sha256:dce2bfd0f285c3fcff89e4239c55f5fbe664ff435ee45abfc154aac0f222ab14",
|
||||
"sha256:dfb8bcd45e504e1c26f0bfc404f3edd08f8c8057dfe04fbf6159adc8694ff97a",
|
||||
"sha256:e1900d7f16a03b869be3572e7664757c14316329a4d79ecee5a0083fad8c81b0",
|
||||
"sha256:e2ddfbcb2c4c7cb8f79db49e284280be468699c701b92d30fd1e46a786b39f5b",
|
||||
"sha256:eb4eea028a7ad28458abf8b98ae14af2fd9baeb327a0adb6af05a488e4d9e9a1",
|
||||
"sha256:f3a29bb51e5f9b46004b5be16bcbe4e1b2d2754cbe201e1a0b142c307bdf4c73",
|
||||
"sha256:f553abcb3572242fed87e308a6b91a9bc5a74b801b5d093969391b0500be718b"
|
||||
"sha256:1ca8e1b4c62038bb2da55451385246f51f412c5f5eabd64812c01766a5989b4a",
|
||||
"sha256:298c00ea41a81a491d5b244d295d18369e5aac4b61b77b2de5b249ca61cd6659",
|
||||
"sha256:2aa887683eee493e015545bd69d3d21ac8d5ad582674ec98f4af84511e353e45",
|
||||
"sha256:2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2",
|
||||
"sha256:3da13c2535b7aea94cc2a6d1b1b37746814c74b6e80790daddd55ca5c120a489",
|
||||
"sha256:406ec8cfe0c098fadb18d597dc2ee6de4428d640c0ccafa453f3d9b2e58d29e2",
|
||||
"sha256:4d0db8df9ffae36f416897ad184608d9d7a8c2b46c4612c6bc759b26c073f750",
|
||||
"sha256:530756d2faa40af4c1f74123e1d889bd07feae45bac2fd32f259a35f7aa74151",
|
||||
"sha256:77931df40bb5ce5e13f4de2bfc982b2ddc0198971fbd947776c8bb5050896eb2",
|
||||
"sha256:797a36bd1f69df9e2798e33edb4bd04e5a30478efc08f9428c087f17f65a7045",
|
||||
"sha256:8085bd0ad2034352eee4d4f3e2da985c2749cb7344b939f4d95ead38c2520859",
|
||||
"sha256:8536bc08d130cae6dcba1ea689f2913dfd332d06113904d171f2f56da6228e89",
|
||||
"sha256:a4d412eba5679ede84b41dbe48b1bed8f33131ab9db06c238a235334733acc5e",
|
||||
"sha256:aebecde2adc4a6847094d3bd6a8a9538ef3438a5ea84ac1983fcb167db614461",
|
||||
"sha256:b276cc4deb4a80f9dfd47a41ebb464b1fe91efd8b1b8620cf5ccf8b824b850d6",
|
||||
"sha256:b5a185ae79f899b01ca49f365bdf15a45d78d9856f09b0de1a41b92afce1a07f",
|
||||
"sha256:c4d8977ccda886d88dc3ca789de2f1adc714df912ff3934b3d0a3f3d777deafb",
|
||||
"sha256:c5dd3ffa663c982d7f1be9eb494a8924f6d40e2e2f7d1d27384cfab1b2ac0662",
|
||||
"sha256:ca88f2f7020002638276439a01ffbb0355634907d1aa5ca91f3dc0c2e44e8f3b",
|
||||
"sha256:d2cce1c82a7845d7e2e8a0956c6b7ed3f1661c9acf18eb120fc71e098ab5c6fe",
|
||||
"sha256:d709572d64825d8d59ea112e11cc7faf6007f294e9951324b7574af4251e4de8",
|
||||
"sha256:da8db8374295fb532b4b0c467e66800ef17d100e4d5faa2bbbd6df35502da125",
|
||||
"sha256:e36c7e3b5382cd5669cf199c4a04a0279a43b2a3bdd77627e9b89778ac9ec08c",
|
||||
"sha256:e95a4a6c54d27a84a4624d2af8bb9ee178111604653194ca6880c98dcad92f48",
|
||||
"sha256:ee835def05622e0c8b1435a906491760a43d0c462f065ec9143ec4b8d79f8bff",
|
||||
"sha256:f75009715dcf4a3d680c2338ab19dac5498f8121173a929872950f4fb3a48fbf",
|
||||
"sha256:f8524b8bc89470cec7ac51734907818d3620fb1637f8f8b542d650ebec42a126"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==3.13.0"
|
||||
"version": "==3.14.1"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"git": "git://github.com/guardicore/pyinstaller",
|
||||
"ref": "913259a5cd2baece06b0eed3618eb75b1bc7fad6"
|
||||
"hashes": [
|
||||
"sha256:24035eb9fffa2e3e288b4c1c9710043819efc7203cae5c8c573bec16f4a8e98f",
|
||||
"sha256:59372b950d176fdc5ecea29719a8ab3f194b73a15b7f9875ac2a1de9a3daf5ed",
|
||||
"sha256:62c97cbbdbee30974d607eb1de9afb081eb3adba787c203b00438e21027b829b",
|
||||
"sha256:75a180a658871bc41f9cf94b6f90ffa54e98f5d6a7cdb02d7530f0360afe24f9",
|
||||
"sha256:7f46ab11ec986e4c525b93251063144e12d432a132dbc0070e3030e34c76537a",
|
||||
"sha256:a0b988cfc197d40e3d773b3aa1c7d3e918fc0933b4c15ec3fc5d156f222d82cb",
|
||||
"sha256:b5f1a94150315ea75bf3501be6c8476d65a7209580bb662da06dbdbc4454f375",
|
||||
"sha256:bec57b3b2b6178907255557ec0fc4b5ce5a0474013414cdadea853205c74ed26",
|
||||
"sha256:e2f165cea4470ce8a8349112cd78f48a61413805adc17792a91997a11cfe1d80",
|
||||
"sha256:ebeb87cdbadb2b4e8f991ffd9945ebd4fb3a7303180e63682c3e1ce01b3fdd22",
|
||||
"sha256:ec3ca331d565ffca1b6470c5aaf798885a03708c3d0b15c1b19009126f84c1d4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.9"
|
||||
},
|
||||
"pyinstaller-hooks-contrib": {
|
||||
"hashes": [
|
||||
"sha256:27558072021857d89524c42136feaa2ffe4f003f1bdf0278f9b24f6902c1759c",
|
||||
"sha256:892310e6363655838485ee748bf1c5e5cade7963686d9af8650ee218a3e0b031"
|
||||
"sha256:9765e68552803327d58f6c5eca970bb245b7cdf073e2f912a2a3cb50360bc2d8",
|
||||
"sha256:9fa4ca03d058cba676c3cc16005076ce6a529f144c08b87c69998625fbd84e0a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2021.1"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2022.3"
|
||||
},
|
||||
"pymssql": {
|
||||
"hashes": [
|
||||
|
@ -866,11 +663,11 @@
|
|||
},
|
||||
"pyopenssl": {
|
||||
"hashes": [
|
||||
"sha256:aeca66338f6de19d1aa46ed634c3b9ae519a64b458f8468aec688e7e3c20f200",
|
||||
"sha256:c727930ad54b10fc157015014b666f2d8b41f70c0d03e83ab67624fd3dd5d1e6"
|
||||
"sha256:660b1b1425aac4a1bea1d94168a85d99f0b3144c869dd4390d27629d0087f1bf",
|
||||
"sha256:ea252b38c87425b64116f808355e8da644ef9b07e429398bfece610f893ee2e0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==19.0.0"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==22.0.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
|
@ -882,28 +679,19 @@
|
|||
},
|
||||
"pypsrp": {
|
||||
"hashes": [
|
||||
"sha256:c0912096858ff8c53a3cf22cc46c3ce20e6ec5e2deade342088e87a81dbadac8",
|
||||
"sha256:d7144ad7c798a4dcded20a71c712d63eb4bfb32debe62f3a98f01481384a5558"
|
||||
"sha256:0101345ceb415896fed9b056e7b77d65312089ddc73c4286247ccf1859d4bc4d",
|
||||
"sha256:f5500acd11dfe742d51b7fbb61321ba721038a300d67763dc52babe709db65e7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.7.0"
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"pypykatz": {
|
||||
"hashes": [
|
||||
"sha256:8acd8d69f7b0ab343c593490a0837871b58b5c322ad54ada2fad0fed049349f3",
|
||||
"sha256:b63b19ec6ee8448bbcf7003e6ad1f9d7a2784fd8cee54aebcc5f717792a43200"
|
||||
"sha256:ad397a6ca72033df70fc6655f8922f1ee16d6c5b05e0e40276899217e2f5dbd3",
|
||||
"sha256:bddb2f0729856e3a0e8c481ec90b52a7e497506ee07ef20b99719496dda02b8d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.12"
|
||||
},
|
||||
"pyreadline": {
|
||||
"hashes": [
|
||||
"sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1",
|
||||
"sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e",
|
||||
"sha256:9ce5fa65b8992dfa373bddc5b6e0864ead8f291c94fbfec05fbd5c836162e67b"
|
||||
],
|
||||
"markers": "python_version < '3.8' and sys_platform == 'win32'",
|
||||
"version": "==2.1"
|
||||
"version": "==0.5.2"
|
||||
},
|
||||
"pysmb": {
|
||||
"hashes": [
|
||||
|
@ -914,36 +702,21 @@
|
|||
},
|
||||
"pyspnego": {
|
||||
"hashes": [
|
||||
"sha256:19da2de9d55d73d05b2798d4e5bd7ee5980e573ae50dc2f2bc460df5eaffe5ea",
|
||||
"sha256:27dd07b6b918c289d2820c685b346a198498354cf3a1bfe9ec19cff9fa8fce2f",
|
||||
"sha256:37c4d80a0c90bd2b670c583b2efbd210c26f54b1f7661c0cbc684a954b88c1c3",
|
||||
"sha256:6387b4631120205240d1be25aff7a78d41db9b99bb5803b3ac6b7b6ed80b8920",
|
||||
"sha256:6df4b5233ec28358992adadfef5be76807ca1424e7c0fbf430424759edc85f8b",
|
||||
"sha256:75a0d4be4236f6b7c2ded0b43fd03e942c48cdbe91c2856f45f22884b7e92ddc",
|
||||
"sha256:9235a3159a4e1648d6bb4d170b8d68ecf5b1f55fa2f3157335ce74df5c192468",
|
||||
"sha256:a0d41d43657cd4d4456ca734ec00b6e24c95a144499cfc429371a310c4b10d7a",
|
||||
"sha256:b02c9b61f85c96f969c78f492b35915a590dddabf987687eb1256ef2fd8fbdcb",
|
||||
"sha256:ccb8d9cea310f1715d5ed3d2d092db9bf50ff2762cf94a0dd9dfab7774a727fe",
|
||||
"sha256:e15d16b205fbc5e945244b974312e9796467913f69736fdad262edee0c3c105f",
|
||||
"sha256:f4a00cc3796d34212b391caecb3fd636cdefea798cb4ac231f893bdade674f01"
|
||||
"sha256:05438a4e3e1526134bc2d72213417a06a2c3010f5b7271f3122e635e523c3790",
|
||||
"sha256:12e4da1cbbbd645c0624699a1d99f734161cb9095e9f1fc1c1982ed1b7a44abe",
|
||||
"sha256:185e0c576cde30d8853d9ea1d69c32cb93e98423934263d6c067bec7adc7dc4f",
|
||||
"sha256:3361027e7e86de6b784791e09a7b2ba73d06c0be40f027a7be09e45fc92325a5",
|
||||
"sha256:4971fb166dc9821c98d31d698722d48d0066f1bc63beff8bf3d2a2e60fe507d1",
|
||||
"sha256:58d352d901baab754f63cb0da790c1f798605eb634f7f922df9bb6822d3de3c5",
|
||||
"sha256:77b7c75bed737f24989aab453b9b8cd1c1512dfc5bed7a303a1cb1156fd59959",
|
||||
"sha256:adf2f3e09bc4751c06fab1fedfe734af7f232d79927c753d8981f75a25f791ec",
|
||||
"sha256:c6993ee6bcfe0036d6246324fcb7975daed858a476bfc7bf1d9334911d3dfca2",
|
||||
"sha256:e21fc7283caa16761d46bea54e78cbfe3177c21e3b2d17d9ef213edcd86e1250",
|
||||
"sha256:f05f1a6316a9baeaef243c9420d995c3dc34cfc91841f17db0c793e3fe557728",
|
||||
"sha256:fe8b2a0d7468d904c61ae63275f8234eb055767aaaba66f6d58d86f47a25aa8e"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.3.1"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
|
||||
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.8.0"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c",
|
||||
"sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"
|
||||
],
|
||||
"version": "==2021.3"
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"pywin32": {
|
||||
"hashes": [
|
||||
|
@ -960,7 +733,8 @@
|
|||
"sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee",
|
||||
"sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"
|
||||
],
|
||||
"markers": "python_version < '3.10' and sys_platform == 'win32' and implementation_name == 'cpython'",
|
||||
"index": "pypi",
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==303"
|
||||
},
|
||||
"pywin32-ctypes": {
|
||||
|
@ -968,6 +742,8 @@
|
|||
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
|
||||
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"requests": {
|
||||
|
@ -978,18 +754,6 @@
|
|||
"index": "pypi",
|
||||
"version": "==2.27.1"
|
||||
},
|
||||
"s3transfer": {
|
||||
"hashes": [
|
||||
"sha256:50ed823e1dc5868ad40c8dc92072f757aa0e653a192845c94a3b676f4a62da4c",
|
||||
"sha256:9c1dc369814391a6bda20ebbf4b70a0f34630592c9aa520856bf384916af2803"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.5.0"
|
||||
},
|
||||
"scoutsuite": {
|
||||
"git": "git://github.com/guardicode/ScoutSuite",
|
||||
"ref": "eac33ac5b0a84e4a2e29682cf3568271eb595003"
|
||||
},
|
||||
"service-identity": {
|
||||
"hashes": [
|
||||
"sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34",
|
||||
|
@ -997,14 +761,6 @@
|
|||
],
|
||||
"version": "==21.1.0"
|
||||
},
|
||||
"setuptools": {
|
||||
"hashes": [
|
||||
"sha256:2404879cda71495fc4d5cbc445ed52fdaddf352b36e40be8dcc63147cb4edabe",
|
||||
"sha256:68eb94073fc486091447fcb0501efd6560a0e5a1839ba249e5ff3c4c93f05f90"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==60.5.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
|
@ -1013,38 +769,24 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"sqlitedict": {
|
||||
"hashes": [
|
||||
"sha256:2affcc301aacd4da7511692601ecbde392294205af418498f7d6d3ec0dbcad56"
|
||||
],
|
||||
"version": "==1.7.0"
|
||||
},
|
||||
"tempora": {
|
||||
"hashes": [
|
||||
"sha256:8d743059a4ea496d925f35480c6d206a7160cacebcd6a31e147fb495dcb732af",
|
||||
"sha256:aa21dd1956e29559ecb2f2f2e14fcdb950085222fbbf86e6c946b5e1a8c36b26"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c",
|
||||
"sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"
|
||||
"sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d",
|
||||
"sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==4.62.3"
|
||||
"version": "==4.64.0"
|
||||
},
|
||||
"twisted": {
|
||||
"extras": [
|
||||
"tls"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b",
|
||||
"sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006"
|
||||
"sha256:57f32b1f6838facb8c004c89467840367ad38e9e535f8252091345dba500b4f2",
|
||||
"sha256:5c63c149eb6b8fe1e32a0215b1cef96fabdba04f705d8efb9174b1ccf5b49d49"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.7'",
|
||||
"version": "==21.7.0"
|
||||
"version": "==22.2.0"
|
||||
},
|
||||
"twisted-iocpsupport": {
|
||||
"hashes": [
|
||||
|
@ -1066,11 +808,19 @@
|
|||
},
|
||||
"typing-extensions": {
|
||||
"hashes": [
|
||||
"sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e",
|
||||
"sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"
|
||||
"sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42",
|
||||
"sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.1"
|
||||
"version": "==4.1.1"
|
||||
},
|
||||
"unicrypto": {
|
||||
"hashes": [
|
||||
"sha256:69240f260493346861e639697e2fda245f14656c7df20ae6d9e6b1bb36acb29e",
|
||||
"sha256:822bbf18ca6bc17f98c3029470bd8898e51fcb6a7716f6b1c95ed0bf9e0e4da5"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.0.5"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
|
@ -1089,11 +839,11 @@
|
|||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f",
|
||||
"sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"
|
||||
"sha256:3c5493ece8268fecdcdc9c0b112211acd006354723b280d643ec732b6d4063d6",
|
||||
"sha256:f8e89a20aeabbe8a893c24a461d3ee5dad2123b05cc6abd73ceed01d39c3ae74"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.0.2"
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"winacl": {
|
||||
"hashes": [
|
||||
|
@ -1108,7 +858,7 @@
|
|||
"sha256:a2ad9c0f6d70f6e0e0d1f54b8582054c62d8a09f346b5ccaf55da68628ca10e1",
|
||||
"sha256:a64624a25fc2d3663a2c5376c5291f3c7531e9c8051571de9ca9db8bf25746c2"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"markers": "platform_system == 'Windows'",
|
||||
"version": "==0.0.9"
|
||||
},
|
||||
"winsys-3.x": {
|
||||
|
@ -1127,20 +877,13 @@
|
|||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==1.5.1"
|
||||
},
|
||||
"zc.lockfile": {
|
||||
"hashes": [
|
||||
"sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b",
|
||||
"sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f"
|
||||
],
|
||||
"version": "==2.0"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d",
|
||||
"sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"
|
||||
"sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad",
|
||||
"sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.7.0"
|
||||
"version": "==3.8.0"
|
||||
},
|
||||
"zope.interface": {
|
||||
"hashes": [
|
||||
|
@ -1201,13 +944,6 @@
|
|||
}
|
||||
},
|
||||
"develop": {
|
||||
"future": {
|
||||
"hashes": [
|
||||
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.18.2"
|
||||
},
|
||||
"ldap3": {
|
||||
"hashes": [
|
||||
"sha256:2bc966556fc4d4fa9f445a1c31dc484ee81d44a51ab0e2d0fd05b62cac75daa6",
|
||||
|
@ -1218,13 +954,6 @@
|
|||
],
|
||||
"version": "==2.9.1"
|
||||
},
|
||||
"pefile": {
|
||||
"hashes": [
|
||||
"sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2021.9.3"
|
||||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
|
||||
|
@ -1242,13 +971,6 @@
|
|||
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
|
||||
],
|
||||
"version": "==0.4.8"
|
||||
},
|
||||
"pywin32-ctypes": {
|
||||
"hashes": [
|
||||
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
|
||||
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
|
||||
],
|
||||
"version": "==0.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
from abc import ABCMeta
|
||||
from itertools import product
|
||||
|
||||
GUID = str(uuid.getnode())
|
||||
|
||||
|
@ -28,9 +26,6 @@ class Configuration(object):
|
|||
continue
|
||||
if key in LOCAL_CONFIG_VARS:
|
||||
continue
|
||||
if self._depth_from_commandline and key == "depth":
|
||||
self.max_depth = value
|
||||
continue
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
else:
|
||||
|
@ -70,18 +65,6 @@ class Configuration(object):
|
|||
|
||||
return result
|
||||
|
||||
# Used to keep track of our depth if manually specified
|
||||
_depth_from_commandline = False
|
||||
|
||||
###########################
|
||||
# logging config
|
||||
###########################
|
||||
|
||||
dropper_log_path_windows = "%temp%\\~df1562.tmp"
|
||||
dropper_log_path_linux = "/tmp/user-1562"
|
||||
monkey_log_path_windows = "%temp%\\~df1563.tmp"
|
||||
monkey_log_path_linux = "/tmp/user-1563"
|
||||
|
||||
###########################
|
||||
# dropper config
|
||||
###########################
|
||||
|
@ -89,151 +72,27 @@ class Configuration(object):
|
|||
dropper_set_date = True
|
||||
dropper_date_reference_path_windows = r"%windir%\system32\kernel32.dll"
|
||||
dropper_date_reference_path_linux = "/bin/sh"
|
||||
dropper_target_path_win_32 = r"C:\Windows\temp\monkey32.exe"
|
||||
dropper_target_path_win_64 = r"C:\Windows\temp\monkey64.exe"
|
||||
dropper_target_path_linux = "/tmp/monkey"
|
||||
|
||||
###########################
|
||||
# monkey config
|
||||
###########################
|
||||
# sets whether or not the monkey is alive. if false will stop scanning and exploiting
|
||||
alive = True
|
||||
|
||||
finger_classes = []
|
||||
exploiter_classes = []
|
||||
system_info_collector_classes = []
|
||||
|
||||
# how many victims to look for in a single scan iteration
|
||||
victims_max_find = 100
|
||||
|
||||
# how many victims to exploit before stopping
|
||||
victims_max_exploit = 100
|
||||
should_stop = False
|
||||
|
||||
# depth of propagation
|
||||
depth = 2
|
||||
max_depth = None
|
||||
started_on_island = False
|
||||
current_server = ""
|
||||
|
||||
# Configuration servers to try to connect to, in this order.
|
||||
command_servers = ["192.0.2.0:5000"]
|
||||
command_servers = []
|
||||
|
||||
keep_tunnel_open_time = 60
|
||||
|
||||
###########################
|
||||
# scanners config
|
||||
###########################
|
||||
|
||||
# Auto detect and scan local subnets
|
||||
local_network_scan = True
|
||||
|
||||
subnet_scan_list = []
|
||||
inaccessible_subnets = []
|
||||
|
||||
blocked_ips = []
|
||||
|
||||
# TCP Scanner
|
||||
HTTP_PORTS = [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8008, # HTTP alternate
|
||||
7001, # Oracle Weblogic default server port
|
||||
]
|
||||
tcp_target_ports = [22, 2222, 445, 135, 3389, 80, 8080, 443, 8008, 3306, 9200]
|
||||
tcp_target_ports.extend(HTTP_PORTS)
|
||||
tcp_scan_timeout = 3000 # 3000 Milliseconds
|
||||
tcp_scan_interval = 0 # in milliseconds
|
||||
tcp_scan_get_banner = True
|
||||
|
||||
# Ping Scanner
|
||||
ping_scan_timeout = 1000
|
||||
|
||||
###########################
|
||||
# exploiters config
|
||||
###########################
|
||||
|
||||
skip_exploit_if_file_exist = False
|
||||
|
||||
ms08_067_exploit_attempts = 5
|
||||
user_to_add = "Monkey_IUSER_SUPPORT"
|
||||
|
||||
###########################
|
||||
# ransomware config
|
||||
###########################
|
||||
|
||||
ransomware = ""
|
||||
|
||||
def get_exploit_user_password_pairs(self):
|
||||
"""
|
||||
Returns all combinations of the configurations users and passwords
|
||||
:return:
|
||||
"""
|
||||
return product(self.exploit_user_list, self.exploit_password_list)
|
||||
|
||||
def get_exploit_user_ssh_key_pairs(self):
|
||||
"""
|
||||
:return: All combinations of the configurations users and ssh pairs
|
||||
"""
|
||||
return product(self.exploit_user_list, self.exploit_ssh_keys)
|
||||
|
||||
def get_exploit_user_password_or_hash_product(self):
|
||||
"""
|
||||
Returns all combinations of the configurations users and passwords or lm/ntlm hashes
|
||||
:return:
|
||||
"""
|
||||
cred_list = []
|
||||
for cred in product(self.exploit_user_list, self.exploit_password_list, [""], [""]):
|
||||
cred_list.append(cred)
|
||||
for cred in product(self.exploit_user_list, [""], [""], self.exploit_ntlm_hash_list):
|
||||
cred_list.append(cred)
|
||||
for cred in product(self.exploit_user_list, [""], self.exploit_lm_hash_list, [""]):
|
||||
cred_list.append(cred)
|
||||
return cred_list
|
||||
|
||||
@staticmethod
|
||||
def hash_sensitive_data(sensitive_data):
|
||||
"""
|
||||
Hash sensitive data (e.g. passwords). Used so the log won't contain sensitive data
|
||||
plain-text, as the log is
|
||||
saved on client machines plain-text.
|
||||
|
||||
:param sensitive_data: the data to hash.
|
||||
:return: the hashed data.
|
||||
"""
|
||||
password_hashed = hashlib.sha512(sensitive_data.encode()).hexdigest()
|
||||
return password_hashed
|
||||
|
||||
exploit_user_list = ["Administrator", "root", "user"]
|
||||
exploit_password_list = ["Password1!", "1234", "password", "12345678"]
|
||||
exploit_lm_hash_list = []
|
||||
exploit_ntlm_hash_list = []
|
||||
exploit_ssh_keys = []
|
||||
|
||||
aws_access_key_id = ""
|
||||
aws_secret_access_key = ""
|
||||
aws_session_token = ""
|
||||
|
||||
# smb/wmi exploiter
|
||||
smb_download_timeout = 300 # timeout in seconds
|
||||
smb_service_name = "InfectionMonkey"
|
||||
|
||||
###########################
|
||||
# post breach actions
|
||||
###########################
|
||||
post_breach_actions = []
|
||||
custom_PBA_linux_cmd = ""
|
||||
custom_PBA_windows_cmd = ""
|
||||
PBA_linux_filename = None
|
||||
PBA_windows_filename = None
|
||||
keep_tunnel_open_time = 30
|
||||
|
||||
###########################
|
||||
# testing configuration
|
||||
###########################
|
||||
export_monkey_telems = False
|
||||
|
||||
def get_hop_distance_to_island(self):
|
||||
return self.max_depth - self.depth
|
||||
|
||||
|
||||
WormConfiguration = Configuration()
|
||||
|
|
|
@ -1,33 +1,24 @@
|
|||
import json
|
||||
import logging
|
||||
import platform
|
||||
from datetime import datetime
|
||||
from pprint import pformat
|
||||
from socket import gethostname
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
import infection_monkey.monkeyfs as monkeyfs
|
||||
import infection_monkey.tunnel as tunnel
|
||||
from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
|
||||
from common.common_consts.time_formats import DEFAULT_TIME_FORMAT
|
||||
from common.common_consts.timeouts import (
|
||||
LONG_REQUEST_TIMEOUT,
|
||||
MEDIUM_REQUEST_TIMEOUT,
|
||||
SHORT_REQUEST_TIMEOUT,
|
||||
)
|
||||
from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT, MEDIUM_REQUEST_TIMEOUT
|
||||
from infection_monkey.config import GUID, WormConfiguration
|
||||
from infection_monkey.network.info import local_ips
|
||||
from infection_monkey.network.info import get_host_subnets, local_ips
|
||||
from infection_monkey.transport.http import HTTPConnectProxy
|
||||
from infection_monkey.transport.tcp import TcpProxy
|
||||
from infection_monkey.utils import agent_process
|
||||
from infection_monkey.utils.environment import is_windows_os
|
||||
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
DOWNLOAD_CHUNK = 1024
|
||||
|
||||
PBA_FILE_DOWNLOAD = "https://%s/api/pba/download/%s"
|
||||
|
||||
|
@ -53,10 +44,11 @@ class ControlClient(object):
|
|||
"guid": GUID,
|
||||
"hostname": hostname,
|
||||
"ip_addresses": local_ips(),
|
||||
"networks": get_host_subnets(),
|
||||
"description": " ".join(platform.uname()),
|
||||
"config": WormConfiguration.as_dict(),
|
||||
"parent": parent,
|
||||
"launch_time": str(datetime.now().strftime(DEFAULT_TIME_FORMAT)),
|
||||
"launch_time": agent_process.get_start_time(),
|
||||
}
|
||||
|
||||
if ControlClient.proxies:
|
||||
|
@ -138,28 +130,6 @@ class ControlClient(object):
|
|||
else:
|
||||
ControlClient.proxies["https"] = f"{proxy_address}:{proxy_port}"
|
||||
|
||||
@staticmethod
|
||||
def keepalive():
|
||||
if not WormConfiguration.current_server:
|
||||
return
|
||||
try:
|
||||
monkey = {}
|
||||
if ControlClient.proxies:
|
||||
monkey["tunnel"] = ControlClient.proxies.get("https")
|
||||
requests.patch( # noqa: DUO123
|
||||
"https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID),
|
||||
data=json.dumps(monkey),
|
||||
headers={"content-type": "application/json"},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def send_telemetry(telem_category, json_data: str):
|
||||
if not WormConfiguration.current_server:
|
||||
|
@ -208,7 +178,7 @@ class ControlClient(object):
|
|||
return
|
||||
try:
|
||||
reply = requests.get( # noqa: DUO123
|
||||
"https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID),
|
||||
"https://%s/api/monkey/%s/legacy" % (WormConfiguration.current_server, GUID),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
|
@ -258,108 +228,6 @@ class ControlClient(object):
|
|||
)
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def check_for_stop():
|
||||
ControlClient.load_control_config()
|
||||
return not WormConfiguration.alive
|
||||
|
||||
@staticmethod
|
||||
def download_monkey_exe(host):
|
||||
filename, size = ControlClient.get_monkey_exe_filename_and_size_by_host(host)
|
||||
if filename is None:
|
||||
return None
|
||||
return ControlClient.download_monkey_exe_by_filename(filename, size)
|
||||
|
||||
@staticmethod
|
||||
def download_monkey_exe_by_os(is_windows, is_32bit):
|
||||
filename, size = ControlClient.get_monkey_exe_filename_and_size_by_host_dict(
|
||||
ControlClient.spoof_host_os_info(is_windows, is_32bit)
|
||||
)
|
||||
if filename is None:
|
||||
return None
|
||||
return ControlClient.download_monkey_exe_by_filename(filename, size)
|
||||
|
||||
@staticmethod
|
||||
def spoof_host_os_info(is_windows, is_32bit):
|
||||
if is_windows:
|
||||
os = "windows"
|
||||
if is_32bit:
|
||||
arch = "x86"
|
||||
else:
|
||||
arch = "amd64"
|
||||
else:
|
||||
os = "linux"
|
||||
if is_32bit:
|
||||
arch = "i686"
|
||||
else:
|
||||
arch = "x86_64"
|
||||
|
||||
return {"os": {"type": os, "machine": arch}}
|
||||
|
||||
@staticmethod
|
||||
def download_monkey_exe_by_filename(filename, size):
|
||||
if not WormConfiguration.current_server:
|
||||
return None
|
||||
try:
|
||||
dest_file = monkeyfs.virtual_path(filename)
|
||||
if (monkeyfs.isfile(dest_file)) and (size == monkeyfs.getsize(dest_file)):
|
||||
return dest_file
|
||||
else:
|
||||
download = requests.get( # noqa: DUO123
|
||||
"https://%s/api/monkey/download/%s"
|
||||
% (WormConfiguration.current_server, filename),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
|
||||
with monkeyfs.open(dest_file, "wb") as file_obj:
|
||||
for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
|
||||
if chunk:
|
||||
file_obj.write(chunk)
|
||||
file_obj.flush()
|
||||
if size == monkeyfs.getsize(dest_file):
|
||||
return dest_file
|
||||
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_monkey_exe_filename_and_size_by_host(host):
|
||||
return ControlClient.get_monkey_exe_filename_and_size_by_host_dict(host.as_dict())
|
||||
|
||||
@staticmethod
|
||||
def get_monkey_exe_filename_and_size_by_host_dict(host_dict):
|
||||
if not WormConfiguration.current_server:
|
||||
return None, None
|
||||
try:
|
||||
reply = requests.post( # noqa: DUO123
|
||||
"https://%s/api/monkey/download" % (WormConfiguration.current_server,),
|
||||
data=json.dumps(host_dict),
|
||||
headers={"content-type": "application/json"},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=LONG_REQUEST_TIMEOUT,
|
||||
)
|
||||
if 200 == reply.status_code:
|
||||
result_json = reply.json()
|
||||
filename = result_json.get("filename")
|
||||
if not filename:
|
||||
return None, None
|
||||
size = result_json.get("size")
|
||||
return filename, size
|
||||
else:
|
||||
return None, None
|
||||
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
"Error connecting to control server %s: %s", WormConfiguration.current_server, exc
|
||||
)
|
||||
|
||||
return None, None
|
||||
|
||||
@staticmethod
|
||||
def create_control_tunnel():
|
||||
if not WormConfiguration.current_server:
|
||||
|
@ -377,7 +245,12 @@ class ControlClient(object):
|
|||
proxy_class = HTTPConnectProxy
|
||||
target_addr, target_port = None, None
|
||||
|
||||
return tunnel.MonkeyTunnel(proxy_class, target_addr=target_addr, target_port=target_port)
|
||||
return tunnel.MonkeyTunnel(
|
||||
proxy_class,
|
||||
keep_tunnel_open_time=WormConfiguration.keep_tunnel_open_time,
|
||||
target_addr=target_addr,
|
||||
target_port=target_port,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_pba_file(filename):
|
||||
|
@ -390,55 +263,3 @@ class ControlClient(object):
|
|||
)
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_T1216_pba_file():
|
||||
try:
|
||||
return requests.get( # noqa: DUO123
|
||||
urljoin(
|
||||
f"https://{WormConfiguration.current_server}/",
|
||||
T1216_PBA_FILE_DOWNLOAD_PATH,
|
||||
),
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies,
|
||||
stream=True,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def should_monkey_run(vulnerable_port: str) -> bool:
|
||||
if (
|
||||
vulnerable_port
|
||||
and WormConfiguration.get_hop_distance_to_island() > 1
|
||||
and ControlClient.can_island_see_port(vulnerable_port)
|
||||
and WormConfiguration.started_on_island
|
||||
):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def can_island_see_port(port):
|
||||
try:
|
||||
url = (
|
||||
f"https://{WormConfiguration.current_server}/api/monkey_control"
|
||||
f"/check_remote_port/{port}"
|
||||
)
|
||||
response = requests.get( # noqa: DUO123
|
||||
url, verify=False, timeout=SHORT_REQUEST_TIMEOUT
|
||||
)
|
||||
response = json.loads(response.content.decode())
|
||||
return response["status"] == "port_visible"
|
||||
except requests.exceptions.RequestException:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def report_start_on_island():
|
||||
requests.post( # noqa: DUO123
|
||||
f"https://{WormConfiguration.current_server}/api/monkey_control/started_on_island",
|
||||
data=json.dumps({"started_on_island": True}),
|
||||
verify=False,
|
||||
timeout=MEDIUM_REQUEST_TIMEOUT,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
from .credential_components.nt_hash import NTHash
|
||||
from .credential_components.lm_hash import LMHash
|
||||
from .credential_components.password import Password
|
||||
from .credential_components.username import Username
|
||||
from .credential_components.ssh_keypair import SSHKeypair
|
||||
from .mimikatz_collector import MimikatzCredentialCollector
|
||||
from .ssh_collector import SSHCredentialCollector
|
|
@ -0,0 +1,12 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from common.common_consts.credential_component_type import CredentialComponentType
|
||||
from infection_monkey.i_puppet import ICredentialComponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class LMHash(ICredentialComponent):
|
||||
credential_type: CredentialComponentType = field(
|
||||
default=CredentialComponentType.LM_HASH, init=False
|
||||
)
|
||||
lm_hash: str
|
|
@ -0,0 +1,12 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from common.common_consts.credential_component_type import CredentialComponentType
|
||||
from infection_monkey.i_puppet import ICredentialComponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class NTHash(ICredentialComponent):
|
||||
credential_type: CredentialComponentType = field(
|
||||
default=CredentialComponentType.NT_HASH, init=False
|
||||
)
|
||||
nt_hash: str
|
|
@ -0,0 +1,12 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from common.common_consts.credential_component_type import CredentialComponentType
|
||||
from infection_monkey.i_puppet import ICredentialComponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Password(ICredentialComponent):
|
||||
credential_type: CredentialComponentType = field(
|
||||
default=CredentialComponentType.PASSWORD, init=False
|
||||
)
|
||||
password: str
|
|
@ -0,0 +1,13 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from common.common_consts.credential_component_type import CredentialComponentType
|
||||
from infection_monkey.i_puppet import ICredentialComponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class SSHKeypair(ICredentialComponent):
|
||||
credential_type: CredentialComponentType = field(
|
||||
default=CredentialComponentType.SSH_KEYPAIR, init=False
|
||||
)
|
||||
private_key: str
|
||||
public_key: str
|
|
@ -0,0 +1,12 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from common.common_consts.credential_component_type import CredentialComponentType
|
||||
from infection_monkey.i_puppet import ICredentialComponent
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Username(ICredentialComponent):
|
||||
credential_type: CredentialComponentType = field(
|
||||
default=CredentialComponentType.USERNAME, init=False
|
||||
)
|
||||
username: str
|
|
@ -0,0 +1 @@
|
|||
from .mimikatz_credential_collector import MimikatzCredentialCollector
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue