From aad9e5069ecb0ad59b863375c76308ceef3f3948 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 30 Jun 2020 16:07:43 +0300 Subject: [PATCH 01/40] PBA file refactoring almost working --- monkey/monkey_island/cc/server_config.json | 6 +- .../configuration-components/PbaInput.js | 91 ++++++++ .../configuration-components/UiSchema.js | 70 ++++++ .../ui/src/components/pages/ConfigurePage.js | 204 +++++------------- .../ui-components/AdvancedMultipleSelect.js | 50 +++++ 5 files changed, 270 insertions(+), 151 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js diff --git a/monkey/monkey_island/cc/server_config.json b/monkey/monkey_island/cc/server_config.json index ecc4c1708..708b5c29c 100644 --- a/monkey/monkey_island/cc/server_config.json +++ b/monkey/monkey_island/cc/server_config.json @@ -1,4 +1,6 @@ { "server_config": "password", - "deployment": "develop" -} + "deployment": "develop", + "user": "test", + "password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14" +} \ No newline at end of file diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js new file mode 100644 index 000000000..1d1e43be4 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js @@ -0,0 +1,91 @@ +import React from 'react'; +import AuthComponent from '../AuthComponent'; + +import {FilePond} from 'react-filepond'; +import 'filepond/dist/filepond.min.css'; + + +class PbaInput extends AuthComponent { + + constructor(props) { + super(props); + console.log("Constructor called"); + // set schema from server + this.state = this.getStateFromProps(this.props); + } + + getStateFromProps(props){ + let options = props.options + // set schema from server + return { + PBAFile: options.PbaFile, + filename: options.filename, + apiEndpoint: options.apiEndpoint, + setPbaFile: options.setPbaFile + }; + } + + getPBAfile() { + if (this.state.PBAFile.length !== 0) { + return this.state.PBAFile + return PbaInput.getMockPBAfile(this.state.PBAFile) + } else if (this.state.filename) { + return PbaInput.getFullPBAfile(this.state.filename) + } + } + + static getMockPBAfile(mockFile) { + let pbaFile = [{ + name: mockFile.name, + source: mockFile.name, + options: { + type: 'limbo' + } + }]; + pbaFile[0].options.file = mockFile; + return pbaFile + } + + + static getFullPBAfile(filename) { + return [{ + source: filename, + options: { + type: 'limbo' + } + }]; + } + + getServerParams(path) { + return { + url: path, + process: this.getRequestParams(), + revert: this.getRequestParams(), + restore: this.getRequestParams(), + load: this.getRequestParams(), + fetch: this.getRequestParams() + } + } + + getRequestParams() { + return {headers: {'Authorization': this.jwtHeader}} + } + + render() { + return ( { + if (fileItems.length > 0) { + this.state.setPbaFile([fileItems[0].file], fileItems[0].file.name) + } else { + this.state.setPbaFile([], "") + } + }} + />) + } +} + + +export default PbaInput; diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js new file mode 100644 index 000000000..ba1a6b19e --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -0,0 +1,70 @@ +import ArrayFieldTemplate from "../ui-components/AdvancedMultipleSelect"; +import PbaInput from "./PbaInput"; +import {API_PBA_LINUX, API_PBA_WINDOWS} from '../pages/ConfigurePage'; + +export default function UiSchema(props) { + const UiSchema = { + basic: { + 'ui:order': ['general', 'credentials'], + credentials: { + exploit_password_list: { + "ui:ArrayFieldTemplate": ArrayFieldTemplate + } + } + }, + basic_network: {}, + monkey: { + behaviour: { + custom_PBA_linux_cmd: { + 'ui:widget': 'textarea', + 'ui:emptyValue': '' + }, + PBA_linux_file: { + 'ui:widget': PbaInput, + 'ui:options': { + PbaFile: props.configuration.PBAlinuxFile, + filename: props.configuration.configuration.monkey.behaviour.PBA_linux_filename, + apiEndpoint: API_PBA_LINUX, + setPbaFile: props.setPbaFileLinux + } + }, + custom_PBA_windows_cmd: { + 'ui:widget': 'textarea', + 'ui:emptyValue': '' + }, + PBA_windows_file: { + 'ui:widget': PbaInput, + 'ui:options': { + PbaFile: props.configuration.PBAwindowsFile, + filename: props.configuration.configuration.monkey.behaviour.PBA_windows_filename, + apiEndpoint: API_PBA_WINDOWS, + setPbaFile: props.setPbaFileWindows + } + }, + PBA_linux_filename: { + classNames: 'linux-pba-file-info', + 'ui:emptyValue': '' + }, + PBA_windows_filename: { + classNames: 'windows-pba-file-info', + 'ui:emptyValue': '' + } + } + }, + cnc: {}, + network: {}, + exploits: { + general: { + exploiter_classes: { + "ui:ArrayFieldTemplate": ArrayFieldTemplate + } + } + }, + internal: { + general: { + started_on_island: {'ui:widget': 'hidden'} + } + } + } + return UiSchema[props.configuration.selectedSection] +} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 2472f5adc..ca07d3604 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -3,9 +3,8 @@ import Form from 'react-jsonschema-form-bs4'; import {Col, Modal, Nav, Button} from 'react-bootstrap'; import FileSaver from 'file-saver'; import AuthComponent from '../AuthComponent'; -import {FilePond} from 'react-filepond'; -import 'filepond/dist/filepond.min.css'; import ConfigMatrixComponent from '../attack/ConfigMatrixComponent'; +import UiSchema from '../configuration-components/UiSchema'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; @@ -13,20 +12,19 @@ import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamati const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; +export const API_PBA_LINUX = '/api/fileUpload/PBAlinux'; +export const API_PBA_WINDOWS = '/api/fileUpload/PBAwindows'; class ConfigurePageComponent extends AuthComponent { constructor(props) { super(props); - this.PBAwindowsPond = null; - this.PBAlinuxPond = null; this.currentSection = 'attack'; this.currentFormData = {}; this.initialConfig = {}; this.initialAttackConfig = {}; this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal']; - this.uiSchemas = this.getUiSchemas(); - // set schema from server + this.state = { schema: {}, configuration: {}, @@ -34,51 +32,11 @@ class ConfigurePageComponent extends AuthComponent { lastAction: 'none', sections: [], selectedSection: 'attack', - PBAwinFile: [], - PBAlinuxFile: [], - showAttackAlert: false - }; - } + showAttackAlert: false, - getUiSchemas() { - return ({ - basic: {'ui:order': ['general', 'credentials']}, - basic_network: {}, - monkey: { - behaviour: { - custom_PBA_linux_cmd: { - 'ui:widget': 'textarea', - 'ui:emptyValue': '' - }, - PBA_linux_file: { - 'ui:widget': this.PBAlinux - }, - custom_PBA_windows_cmd: { - 'ui:widget': 'textarea', - 'ui:emptyValue': '' - }, - PBA_windows_file: { - 'ui:widget': this.PBAwindows - }, - PBA_linux_filename: { - classNames: 'linux-pba-file-info', - 'ui:emptyValue': '' - }, - PBA_windows_filename: { - classNames: 'windows-pba-file-info', - 'ui:emptyValue': '' - } - } - }, - cnc: {}, - network: {}, - exploits: {}, - internal: { - general: { - started_on_island: {'ui:widget': 'hidden'} - } - } - }) + PBAwindowsFile: [], + PBAlinuxFile: [] + }; } setInitialConfig(config) { @@ -122,7 +80,7 @@ class ConfigurePageComponent extends AuthComponent { .then(res => res.json()) .then(data => { this.setInitialConfig(data.configuration); - this.setState({configuration: data.configuration}) + this.setState({configuration: data.configuration}); }) }; @@ -271,7 +229,6 @@ class ConfigurePageComponent extends AuthComponent { }; resetConfig = () => { - this.removePBAfiles(); this.authFetch(CONFIG_URL, { method: 'POST', @@ -280,14 +237,15 @@ class ConfigurePageComponent extends AuthComponent { }) .then(res => res.json()) .then(res => { - this.setState({ - lastAction: 'reset', - schema: res.schema, - configuration: res.configuration - }); - this.setInitialConfig(res.configuration); - this.props.onStatusChange(); - }); + this.setState({ + lastAction: 'reset', + schema: res.schema, + configuration: res.configuration + }); + this.setInitialConfig(res.configuration); + this.props.onStatusChange(); + } + ); this.authFetch(ATTACK_URL, { method: 'POST', headers: {'Content-Type': 'application/json'}, @@ -298,23 +256,22 @@ class ConfigurePageComponent extends AuthComponent { this.setState({attackConfig: res.configuration}); this.setInitialAttackConfig(res.configuration); }) + + this.removePBAfile(API_PBA_WINDOWS, this.setPbaFileWindows) + this.removePBAfile(API_PBA_LINUX, this.setPbaFileLinux) }; - removePBAfiles() { - // We need to clean files from widget, local state and configuration (to sync with bac end) - if (this.PBAwindowsPond !== null) { - this.PBAwindowsPond.removeFile(); - } - if (this.PBAlinuxPond !== null) { - this.PBAlinuxPond.removeFile(); - } + removePBAfile(apiEndpoint, setParamsFnc) { + this.sendPbaRemoveRequest(apiEndpoint) + setParamsFnc([], "") + } + + sendPbaRemoveRequest(apiEndpoint) { let request_options = { method: 'DELETE', headers: {'Content-Type': 'text/plain'} }; - this.authFetch('/api/fileUpload/PBAlinux', request_options); - this.authFetch('/api/fileUpload/PBAwindows', request_options); - this.setState({PBAlinuxFile: [], PBAwinFile: []}); + this.authFetch(apiEndpoint, request_options); } setConfigOnImport = (event) => { @@ -366,82 +323,6 @@ class ConfigurePageComponent extends AuthComponent { event.target.value = null; }; - PBAwindows = () => { - return ( { - this.setState({ - PBAwinFile: fileItems.map(fileItem => fileItem.file) - }) - }} - ref={ref => this.PBAwindowsPond = ref} - />) - }; - - PBAlinux = () => { - return ( { - this.setState({ - PBAlinuxFile: fileItems.map(fileItem => fileItem.file) - }) - }} - ref={ref => this.PBAlinuxPond = ref} - />) - }; - - getWinPBAfile() { - if (this.state.PBAwinFile.length !== 0) { - return ConfigurePageComponent.getMockPBAfile(this.state.PBAwinFile[0]) - } else if (this.state.configuration.monkey.behaviour.PBA_windows_filename) { - return ConfigurePageComponent.getFullPBAfile(this.state.configuration.monkey.behaviour.PBA_windows_filename) - } - } - - getLinuxPBAfile() { - if (this.state.PBAlinuxFile.length !== 0) { - return ConfigurePageComponent.getMockPBAfile(this.state.PBAlinuxFile[0]) - } else if (this.state.configuration.monkey.behaviour.PBA_linux_filename) { - return ConfigurePageComponent.getFullPBAfile(this.state.configuration.monkey.behaviour.PBA_linux_filename) - } - } - - static getFullPBAfile(filename) { - return [{ - source: filename, - options: { - type: 'limbo' - } - }]; - } - - static getMockPBAfile(mockFile) { - let pbaFile = [{ - source: mockFile.name, - options: { - type: 'limbo' - } - }]; - pbaFile[0].options.file = mockFile; - return pbaFile - } - renderMatrix = () => { return () }; - renderConfigContent = (displayedSchema) => { return (
{this.renderBasicNetworkWarning()}
) }; + setPbaFileWindows = (pbaFile, filename) => { + let pbaFileDeepCopy = JSON.parse(JSON.stringify(pbaFile)) + let config = this.state.configuration + config.monkey.behaviour.PBA_windows_filename = filename + this.setState({ + PBAwindowsFile: pbaFileDeepCopy, + configuration: config + }) + } + + setPbaFileLinux = (pbaFile, filename) => { + let pbaFileDeepCopy = JSON.parse(JSON.stringify(pbaFile)) + let config = this.state.configuration + config.monkey.behaviour.PBA_linux_filename = filename + console.log(config); + this.setState({ + PBAlinuxFile: pbaFileDeepCopy, + configuration: config + }) + } + renderBasicNetworkWarning = () => { if (this.state.selectedSection === 'basic_network') { return (
@@ -495,6 +400,7 @@ class ConfigurePageComponent extends AuthComponent { displayedSchema = this.state.schema['properties'][this.state.selectedSection]; displayedSchema['definitions'] = this.state.schema['definitions']; } + let content = ''; if (this.state.selectedSection === 'attack' && Object.entries(this.state.attackConfig).length !== 0) { content = this.renderMatrix() diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js new file mode 100644 index 000000000..70e0953a0 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js @@ -0,0 +1,50 @@ +import React from "react"; +import Button from 'react-bootstrap/Button'; + + +function ArrayFieldTemplate(props) { + return ( +
+ {props.items && + props.items.map(element => ( +
+
{element.children}
+ {element.hasMoveDown && ( + + )} + {element.hasMoveUp && ( + + )} + +
+
+ ))} + + {props.canAdd && ( +
+

+ +

+
+ )} +
+ ); +} + +export default ArrayFieldTemplate; From fda600eb602cb3ac5dd93baca4aa9b7f33e3a38a Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 30 Jun 2020 18:10:48 +0300 Subject: [PATCH 02/40] Finished PBA refactoring --- .../configuration-components/PbaInput.js | 32 ++++++------------- .../configuration-components/UiSchema.js | 12 +++---- .../ui/src/components/pages/ConfigurePage.js | 32 ++++++++----------- 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js index 1d1e43be4..f341a085e 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js @@ -9,7 +9,6 @@ class PbaInput extends AuthComponent { constructor(props) { super(props); - console.log("Constructor called"); // set schema from server this.state = this.getStateFromProps(this.props); } @@ -18,35 +17,24 @@ class PbaInput extends AuthComponent { let options = props.options // set schema from server return { - PBAFile: options.PbaFile, filename: options.filename, apiEndpoint: options.apiEndpoint, - setPbaFile: options.setPbaFile + setPbaFilename: options.setPbaFilename }; } - getPBAfile() { - if (this.state.PBAFile.length !== 0) { - return this.state.PBAFile - return PbaInput.getMockPBAfile(this.state.PBAFile) - } else if (this.state.filename) { - return PbaInput.getFullPBAfile(this.state.filename) + componentDidUpdate(prevProps, prevState, snapshot) { + if(prevProps.options.filename !== this.props.options.filename && this.props.options.filename === ""){ + this.setState({filename: this.props.options.filename}) } } - static getMockPBAfile(mockFile) { - let pbaFile = [{ - name: mockFile.name, - source: mockFile.name, - options: { - type: 'limbo' - } - }]; - pbaFile[0].options.file = mockFile; - return pbaFile + getPBAfile() { + if (this.state.filename) { + return PbaInput.getFullPBAfile(this.state.filename) + } } - static getFullPBAfile(filename) { return [{ source: filename, @@ -78,9 +66,9 @@ class PbaInput extends AuthComponent { files={this.getPBAfile()} onupdatefiles={fileItems => { if (fileItems.length > 0) { - this.state.setPbaFile([fileItems[0].file], fileItems[0].file.name) + this.state.setPbaFilename(fileItems[0].file.name) } else { - this.state.setPbaFile([], "") + this.state.setPbaFilename("") } }} />) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index ba1a6b19e..a9c592d7c 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -22,10 +22,9 @@ export default function UiSchema(props) { PBA_linux_file: { 'ui:widget': PbaInput, 'ui:options': { - PbaFile: props.configuration.PBAlinuxFile, - filename: props.configuration.configuration.monkey.behaviour.PBA_linux_filename, + filename: props.PBA_linux_filename, apiEndpoint: API_PBA_LINUX, - setPbaFile: props.setPbaFileLinux + setPbaFilename: props.setPbaFilenameLinux } }, custom_PBA_windows_cmd: { @@ -35,10 +34,9 @@ export default function UiSchema(props) { PBA_windows_file: { 'ui:widget': PbaInput, 'ui:options': { - PbaFile: props.configuration.PBAwindowsFile, - filename: props.configuration.configuration.monkey.behaviour.PBA_windows_filename, + filename: props.PBA_windows_filename, apiEndpoint: API_PBA_WINDOWS, - setPbaFile: props.setPbaFileWindows + setPbaFilename: props.setPbaFilenameWindows } }, PBA_linux_filename: { @@ -66,5 +64,5 @@ export default function UiSchema(props) { } } } - return UiSchema[props.configuration.selectedSection] + return UiSchema[props.selectedSection] } diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index ca07d3604..e75978b7f 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -33,9 +33,6 @@ class ConfigurePageComponent extends AuthComponent { sections: [], selectedSection: 'attack', showAttackAlert: false, - - PBAwindowsFile: [], - PBAlinuxFile: [] }; } @@ -245,7 +242,10 @@ class ConfigurePageComponent extends AuthComponent { this.setInitialConfig(res.configuration); this.props.onStatusChange(); } - ); + ).then(() => { + this.removePBAfile(API_PBA_WINDOWS, this.setPbaFilenameWindows) + this.removePBAfile(API_PBA_LINUX, this.setPbaFilenameLinux) + }); this.authFetch(ATTACK_URL, { method: 'POST', headers: {'Content-Type': 'application/json'}, @@ -257,13 +257,12 @@ class ConfigurePageComponent extends AuthComponent { this.setInitialAttackConfig(res.configuration); }) - this.removePBAfile(API_PBA_WINDOWS, this.setPbaFileWindows) - this.removePBAfile(API_PBA_LINUX, this.setPbaFileLinux) + }; - removePBAfile(apiEndpoint, setParamsFnc) { + removePBAfile(apiEndpoint, setFilenameFnc) { this.sendPbaRemoveRequest(apiEndpoint) - setParamsFnc([], "") + setFilenameFnc("") } sendPbaRemoveRequest(apiEndpoint) { @@ -335,9 +334,11 @@ class ConfigurePageComponent extends AuthComponent { {this.renderBasicNetworkWarning()} ) }; - setPbaFileWindows = (pbaFile, filename) => { - let pbaFileDeepCopy = JSON.parse(JSON.stringify(pbaFile)) + setPbaFilenameWindows = (filename) => { let config = this.state.configuration config.monkey.behaviour.PBA_windows_filename = filename this.setState({ - PBAwindowsFile: pbaFileDeepCopy, configuration: config }) } - setPbaFileLinux = (pbaFile, filename) => { - let pbaFileDeepCopy = JSON.parse(JSON.stringify(pbaFile)) + setPbaFilenameLinux = (filename) => { let config = this.state.configuration config.monkey.behaviour.PBA_linux_filename = filename - console.log(config); this.setState({ - PBAlinuxFile: pbaFileDeepCopy, configuration: config }) } From 67eeb2b6707cac07ea4d2cc993b13a5aa1bab5b7 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 3 Jul 2020 17:38:02 +0300 Subject: [PATCH 03/40] Grouped stylesheets into components and pages --- .../src/components/attack/ConfigMatrixComponent.js | 2 +- .../cc/ui/src/components/pages/LoginPage.js | 2 +- .../cc/ui/src/components/pages/MapPage.js | 2 +- .../cc/ui/src/components/pages/NotFoundPage.js | 2 +- .../cc/ui/src/components/pages/RegisterPage.js | 2 +- .../cc/ui/src/components/pages/StartOverPage.js | 2 +- .../cc/ui/src/components/pages/TelemetryPage.js | 2 +- .../components/report-components/AttackReport.js | 2 +- .../attack/ReportMatrixComponent.js | 2 +- .../zerotrust/SinglePillarPrinciplesStatus.js | 2 +- .../cc/ui/src/components/ui-components/Checkbox.js | 2 +- monkey/monkey_island/cc/ui/src/styles/Main.scss | 14 ++++++++------ .../ui/src/styles/{ => components}/Checkbox.scss | 0 .../ui/src/styles/{ => components}/Collapse.scss | 0 .../cc/ui/src/styles/{ => components}/Map.scss | 0 .../src/styles/{ => components}/PreviewPane.scss | 0 .../cc/ui/src/styles/{ => components}/Tooltip.scss | 0 .../particle-component/AuthPageParams.js | 0 .../cc/ui/src/styles/{ => pages}/AuthPage.scss | 0 .../src/styles/{ => pages}/ConfigurationPage.scss | 0 .../ui/src/styles/{ => pages}/MonkeyRunPage.scss | 0 .../cc/ui/src/styles/{ => pages}/NotFoundPage.scss | 0 .../ui/src/styles/{ => pages}/StartOverPage.scss | 0 .../ui/src/styles/{ => pages}/TelemetryPage.scss | 0 .../styles/{ => pages}/report/AttackReport.scss | 0 .../{ => pages}/report/ReportAttackMatrix.scss | 0 .../src/styles/{ => pages}/report/ReportPage.scss | 0 .../styles/{ => pages}/report/ZeroTrustReport.scss | 0 28 files changed, 19 insertions(+), 17 deletions(-) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/Checkbox.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/Collapse.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/Map.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/PreviewPane.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/Tooltip.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => components}/particle-component/AuthPageParams.js (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/AuthPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/ConfigurationPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/MonkeyRunPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/NotFoundPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/StartOverPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/TelemetryPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/report/AttackReport.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/report/ReportAttackMatrix.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/report/ReportPage.scss (100%) rename monkey/monkey_island/cc/ui/src/styles/{ => pages}/report/ZeroTrustReport.scss (100%) diff --git a/monkey/monkey_island/cc/ui/src/components/attack/ConfigMatrixComponent.js b/monkey/monkey_island/cc/ui/src/components/attack/ConfigMatrixComponent.js index 75c2a2106..ff9a11766 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/ConfigMatrixComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/ConfigMatrixComponent.js @@ -4,7 +4,7 @@ import Tooltip from 'react-tooltip-lite' import AuthComponent from '../AuthComponent'; import ReactTable from 'react-table'; import 'filepond/dist/filepond.min.css'; -import '../../styles/Tooltip.scss'; +import '../../styles/components/Tooltip.scss'; import {Col} from 'react-bootstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js b/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js index 04e1ab506..f617036a6 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js @@ -3,7 +3,7 @@ import {Button, Col, Container, Form, Row} from 'react-bootstrap'; import AuthService from '../../services/AuthService'; import Particles from "react-particles-js"; -import {particleParams} from "../../styles/particle-component/AuthPageParams"; +import {particleParams} from "../../styles/components/particle-component/AuthPageParams"; import monkeyGeneral from "../../images/militant-monkey.svg"; class LoginPageComponent extends React.Component { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js index 11c9174e9..9ca26ae22 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js @@ -8,7 +8,7 @@ import PreviewPaneComponent from 'components/map/preview-pane/PreviewPane'; import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph'; import {getOptions, edgeGroupToColor} from 'components/map/MapOptions'; import AuthComponent from '../AuthComponent'; -import '../../styles/Map.scss'; +import '../../styles/components/Map.scss'; import {faInfoCircle} from "@fortawesome/free-solid-svg-icons/faInfoCircle"; class MapPageComponent extends AuthComponent { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/NotFoundPage.js b/monkey/monkey_island/cc/ui/src/components/pages/NotFoundPage.js index 9696fa521..5cd341574 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/NotFoundPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/NotFoundPage.js @@ -1,6 +1,6 @@ import React from 'react'; -import '../../styles/NotFoundPage.scss'; +import '../../styles/pages/NotFoundPage.scss'; import monkeyDetective from '../../images/detective-monkey.svg'; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js index 62ff0e170..9d7d6dd80 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RegisterPage.js @@ -3,7 +3,7 @@ import {Row, Col, Container, Form, Button} from 'react-bootstrap'; import Particles from 'react-particles-js'; import AuthService from '../../services/AuthService'; -import {particleParams} from '../../styles/particle-component/AuthPageParams'; +import {particleParams} from '../../styles/components/particle-component/AuthPageParams'; import monkeyDetective from '../../images/detective-monkey.svg'; class RegisterPageComponent extends React.Component { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js b/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js index cf38b56cb..5c665bd0e 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js @@ -3,7 +3,7 @@ import {Col, Button} from 'react-bootstrap'; import {Link} from 'react-router-dom'; import AuthComponent from '../AuthComponent'; import StartOverModal from '../ui-components/StartOverModal'; -import '../../styles/StartOverPage.scss'; +import '../../styles/pages/StartOverPage.scss'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faInfoCircle} from "@fortawesome/free-solid-svg-icons/faInfoCircle"; import {faCheck} from "@fortawesome/free-solid-svg-icons/faCheck"; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js b/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js index f5f8b10d4..2d75272a3 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js @@ -6,7 +6,7 @@ import AuthComponent from '../AuthComponent'; import download from 'downloadjs'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import '../../styles/TelemetryPage.scss'; +import '../../styles/pages/TelemetryPage.scss'; import {faDownload} from "@fortawesome/free-solid-svg-icons/faDownload"; const renderJson = (val) => ; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js index 5c066034c..3372d1d33 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js @@ -1,6 +1,6 @@ import React from 'react'; import {Col, Button} from 'react-bootstrap'; -import '../../styles/Collapse.scss'; +import '../../styles/components/Collapse.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import {faCircle} from '@fortawesome/free-solid-svg-icons/faCircle'; import {faRadiation} from '@fortawesome/free-solid-svg-icons/faRadiation'; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/attack/ReportMatrixComponent.js b/monkey/monkey_island/cc/ui/src/components/report-components/attack/ReportMatrixComponent.js index c2d4b0d3f..a110da5ea 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/attack/ReportMatrixComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/attack/ReportMatrixComponent.js @@ -3,7 +3,7 @@ import React from 'react'; import Checkbox from '../../ui-components/Checkbox'; import ReactTable from 'react-table'; import 'filepond/dist/filepond.min.css'; -import '../../../styles/report/ReportAttackMatrix.scss'; +import '../../../styles/pages/report/ReportAttackMatrix.scss'; class ReportMatrixComponent extends React.Component { constructor(props) { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js index 9d637581c..feff49e2a 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js @@ -7,7 +7,7 @@ import {Card, Collapse} from 'react-bootstrap'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faChevronDown} from '@fortawesome/free-solid-svg-icons'; -import '../../../styles/report/ZeroTrustReport.scss'; +import '../../../styles/pages/report/ZeroTrustReport.scss'; export default class SinglePillarPrinciplesStatus extends AuthComponent { diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/Checkbox.js b/monkey/monkey_island/cc/ui/src/components/ui-components/Checkbox.js index 54aaa46ec..fdf3acd4f 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/Checkbox.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/Checkbox.js @@ -1,4 +1,4 @@ -import '../../styles/Checkbox.scss' +import '../../styles/components/Checkbox.scss' import React from 'react'; class CheckboxComponent extends React.PureComponent { diff --git a/monkey/monkey_island/cc/ui/src/styles/Main.scss b/monkey/monkey_island/cc/ui/src/styles/Main.scss index 1f06392e0..6b6096a3f 100644 --- a/monkey/monkey_island/cc/ui/src/styles/Main.scss +++ b/monkey/monkey_island/cc/ui/src/styles/Main.scss @@ -3,12 +3,14 @@ @import '../../node_modules/bootstrap/scss/bootstrap'; // Imports that require variables -@import './report/ReportPage.scss'; -@import './report/AttackReport.scss'; -@import './PreviewPane.scss'; -@import './ConfigurationPage.scss'; -@import './AuthPage.scss'; -@import './MonkeyRunPage.scss'; +@import 'pages/report/ReportPage.scss'; +@import 'pages/report/AttackReport.scss'; +@import 'pages/ConfigurationPage'; +@import 'pages/AuthPage'; +@import 'pages/MonkeyRunPage'; +@import 'components/InfoPane'; +@import 'components/PreviewPane'; +@import 'components/AdvancedMultiSelect'; // Define custom elements after bootstrap import diff --git a/monkey/monkey_island/cc/ui/src/styles/Checkbox.scss b/monkey/monkey_island/cc/ui/src/styles/components/Checkbox.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/Checkbox.scss rename to monkey/monkey_island/cc/ui/src/styles/components/Checkbox.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/Collapse.scss b/monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/Collapse.scss rename to monkey/monkey_island/cc/ui/src/styles/components/Collapse.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/Map.scss b/monkey/monkey_island/cc/ui/src/styles/components/Map.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/Map.scss rename to monkey/monkey_island/cc/ui/src/styles/components/Map.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/PreviewPane.scss b/monkey/monkey_island/cc/ui/src/styles/components/PreviewPane.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/PreviewPane.scss rename to monkey/monkey_island/cc/ui/src/styles/components/PreviewPane.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/Tooltip.scss b/monkey/monkey_island/cc/ui/src/styles/components/Tooltip.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/Tooltip.scss rename to monkey/monkey_island/cc/ui/src/styles/components/Tooltip.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/particle-component/AuthPageParams.js b/monkey/monkey_island/cc/ui/src/styles/components/particle-component/AuthPageParams.js similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/particle-component/AuthPageParams.js rename to monkey/monkey_island/cc/ui/src/styles/components/particle-component/AuthPageParams.js diff --git a/monkey/monkey_island/cc/ui/src/styles/AuthPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/AuthPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/AuthPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/ConfigurationPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/MonkeyRunPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/MonkeyRunPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/MonkeyRunPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/MonkeyRunPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/NotFoundPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/NotFoundPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/NotFoundPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/NotFoundPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/StartOverPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/StartOverPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/StartOverPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/StartOverPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/TelemetryPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/TelemetryPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/TelemetryPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/TelemetryPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/report/AttackReport.scss b/monkey/monkey_island/cc/ui/src/styles/pages/report/AttackReport.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/report/AttackReport.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/report/AttackReport.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/report/ReportAttackMatrix.scss b/monkey/monkey_island/cc/ui/src/styles/pages/report/ReportAttackMatrix.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/report/ReportAttackMatrix.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/report/ReportAttackMatrix.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/report/ReportPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/report/ReportPage.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/report/ReportPage.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/report/ReportPage.scss diff --git a/monkey/monkey_island/cc/ui/src/styles/report/ZeroTrustReport.scss b/monkey/monkey_island/cc/ui/src/styles/pages/report/ZeroTrustReport.scss similarity index 100% rename from monkey/monkey_island/cc/ui/src/styles/report/ZeroTrustReport.scss rename to monkey/monkey_island/cc/ui/src/styles/pages/report/ZeroTrustReport.scss From 989020c5bac71954235f6e924cac3e06223f29c4 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 3 Jul 2020 17:38:43 +0300 Subject: [PATCH 04/40] Removed old react-jsonshema-form npm package --- monkey/monkey_island/cc/ui/package-lock.json | 15 --------------- monkey/monkey_island/cc/ui/package.json | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/monkey/monkey_island/cc/ui/package-lock.json b/monkey/monkey_island/cc/ui/package-lock.json index 1a66ea551..4e24e73ae 100644 --- a/monkey/monkey_island/cc/ui/package-lock.json +++ b/monkey/monkey_island/cc/ui/package-lock.json @@ -10566,21 +10566,6 @@ "react-base16-styling": "0.5.3" } }, - "react-jsonschema-form": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/react-jsonschema-form/-/react-jsonschema-form-1.8.1.tgz", - "integrity": "sha512-aaDloxNAcGXOOOcdKOxxqEEn5oDlPUZgWcs8unXXB9vjBRgCF8rCm/wVSv1u2G5ih0j/BX6Ewd/WjI2g00lPdg==", - "requires": { - "@babel/runtime-corejs2": "7.9.6", - "ajv": "6.12.2", - "core-js": "2.6.11", - "lodash": "4.17.15", - "prop-types": "15.7.2", - "react-is": "16.13.1", - "react-lifecycles-compat": "3.0.4", - "shortid": "2.2.15" - } - }, "react-jsonschema-form-bs4": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/react-jsonschema-form-bs4/-/react-jsonschema-form-bs4-1.7.1.tgz", diff --git a/monkey/monkey_island/cc/ui/package.json b/monkey/monkey_island/cc/ui/package.json index 3858a46c8..c2fd4c73e 100644 --- a/monkey/monkey_island/cc/ui/package.json +++ b/monkey/monkey_island/cc/ui/package.json @@ -72,6 +72,7 @@ "file-saver": "^2.0.2", "filepond": "^4.7.3", "jwt-decode": "^2.2.0", + "lodash": "^4.17.15", "marked": "^0.8.2", "normalize.css": "^8.0.0", "npm": "^6.14.5", @@ -92,7 +93,6 @@ "react-graph-vis": "^1.0.5", "react-hot-loader": "^4.12.20", "react-json-tree": "^0.11.2", - "react-jsonschema-form": "^1.8.0", "react-jsonschema-form-bs4": "^1.7.1", "react-particles-js": "^3.2.1", "react-redux": "^5.1.2", From 6a824efab346cef4e64a4a0e45b1ed6980a3e632 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 3 Jul 2020 17:41:41 +0300 Subject: [PATCH 05/40] Finished AdvancedMultiSelect component --- .../cc/services/config_schema.py | 53 +++++++-- .../configuration-components/UiSchema.js | 15 +-- .../ui-components/AdvancedMultiSelect.js | 111 ++++++++++++++++++ .../ui-components/AdvancedMultipleSelect.js | 50 -------- .../src/components/ui-components/InfoPane.js | 52 ++++++++ .../ui-components/utils/HeightCalculator.js | 16 +++ .../ui-components/utils/ObjectPathResolver.js | 11 ++ .../components/AdvancedMultiSelect.scss | 47 ++++++++ .../cc/ui/src/styles/components/InfoPane.scss | 29 +++++ 9 files changed, 315 insertions(+), 69 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js delete mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js create mode 100644 monkey/monkey_island/cc/ui/src/components/ui-components/utils/ObjectPathResolver.js create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss create mode 100644 monkey/monkey_island/cc/ui/src/styles/components/InfoPane.scss diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 30425dc1d..b8f2701c0 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -17,7 +17,10 @@ SCHEMA = { "SmbExploiter" ], "title": "SMB Exploiter", - "attack_techniques": ["T1110", "T1075", "T1035"] + "attack_techniques": ["T1110", "T1075", "T1035"], + "info": "Brute forces using credentials provided by user and" + " hashes gathered by mimikatz.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", @@ -25,7 +28,10 @@ SCHEMA = { "WmiExploiter" ], "title": "WMI Exploiter", - "attack_techniques": ["T1110", "T1106"] + "attack_techniques": ["T1110", "T1106"], + "info": "Brute forces WMI (Windows Management Instrumentation) " + "using credentials provided by user and hashes gathered by mimikatz.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", @@ -33,7 +39,10 @@ SCHEMA = { "MSSQLExploiter" ], "title": "MSSQL Exploiter", - "attack_techniques": ["T1110"] + "attack_techniques": ["T1110"], + "info": "Tries to brute force into MsSQL server and uses insecure " + "configuration to execute commands on server.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", @@ -41,7 +50,9 @@ SCHEMA = { "Ms08_067_Exploiter" ], "title": "MS08-067 Exploiter (UNSAFE)", - "attack_techniques": [] + "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. " + "Uses MS08-067 vulnerability.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", @@ -49,56 +60,74 @@ SCHEMA = { "SSHExploiter" ], "title": "SSH Exploiter", - "attack_techniques": ["T1110", "T1145", "T1106"] + "attack_techniques": ["T1110", "T1145", "T1106"], + "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "ShellShockExploiter" ], - "title": "ShellShock Exploiter" + "title": "ShellShock Exploiter", + "info": "CVE-2014-6271, based on logic in NCC group's github.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "SambaCryExploiter" ], - "title": "SambaCry Exploiter" + "title": "SambaCry Exploiter", + "info": "Bruteforces and searches for anonymous shares. Uses Impacket.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "ElasticGroovyExploiter" ], - "title": "ElasticGroovy Exploiter" + "title": "ElasticGroovy Exploiter", + "info": "CVE-2015-1427. Logic is based on Metasploit module.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "Struts2Exploiter" ], - "title": "Struts2 Exploiter" + "title": "Struts2 Exploiter", + "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on this PoC.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "WebLogicExploiter" ], - "title": "WebLogic Exploiter" + "title": "WebLogic Exploiter", + "info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "HadoopExploiter" ], - "title": "Hadoop/Yarn Exploiter" + "title": "Hadoop/Yarn Exploiter", + "info": "Remote code execution on HADOOP server with YARN and default settings. " + "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { "type": "string", "enum": [ "VSFTPDExploiter" ], - "title": "VSFTPD Exploiter" + "title": "VSFTPD Exploiter", + "info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. " + "Logic based on Metasploit module.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" } ] }, diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index a9c592d7c..7b7d2bfcb 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -1,4 +1,4 @@ -import ArrayFieldTemplate from "../ui-components/AdvancedMultipleSelect"; +import AdvancedMultiSelect from "../ui-components/AdvancedMultiSelect"; import PbaInput from "./PbaInput"; import {API_PBA_LINUX, API_PBA_WINDOWS} from '../pages/ConfigurePage'; @@ -6,11 +6,6 @@ export default function UiSchema(props) { const UiSchema = { basic: { 'ui:order': ['general', 'credentials'], - credentials: { - exploit_password_list: { - "ui:ArrayFieldTemplate": ArrayFieldTemplate - } - } }, basic_network: {}, monkey: { @@ -54,7 +49,13 @@ export default function UiSchema(props) { exploits: { general: { exploiter_classes: { - "ui:ArrayFieldTemplate": ArrayFieldTemplate + 'ui:widget': AdvancedMultiSelect, + 'ui:options': { + defaultPaneParams: { + title: 'Exploiters', + content: 'Click on exploiter to get more information about it.' + } + } } } }, diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js new file mode 100644 index 000000000..f8083060b --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js @@ -0,0 +1,111 @@ +import React, {useState} from 'react'; + +import {Card, Button, Form} from 'react-bootstrap'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faSquare, faCheckSquare} from '@fortawesome/free-solid-svg-icons'; +import {cloneDeep} from 'lodash'; + +import {getComponentHeight} from './utils/HeightCalculator'; +import {resolveObjectPath} from './utils/ObjectPathResolver'; +import InfoPane from './InfoPane'; + + +function getSelectValuesAfterClick(valueArray, clickedValue) { + if (valueArray.includes(clickedValue)) { + return valueArray.filter((e) => { + return e !== clickedValue; + }); + } else { + valueArray.push(clickedValue); + return valueArray; + } +} + +function onMasterCheckboxClick(checkboxValue, defaultArray, onChangeFnc) { + if (checkboxValue) { + onChangeFnc([]); + } else { + onChangeFnc(defaultArray); + } +} + +// Definitions passed to components only contains value and label, +// custom fields like "info" or "links" must be pulled from registry object using this function +function getFullDefinitionsFromRegistry(refString, registry) { + let refArray = refString.replace('#', '').split('/'); + let definitionObject = resolveObjectPath(refArray, registry); + return definitionObject.anyOf; +} + +function getFullDefinitionByKey(refString, registry, itemKey) { + let fullArray = getFullDefinitionsFromRegistry(refString, registry); + return fullArray.filter(e => (e.enum[0] === itemKey))[0]; +} + +function setPaneInfo(refString, registry, itemKey, setPaneInfoFnc) { + let definitionObj = getFullDefinitionByKey(refString, registry, itemKey); + setPaneInfoFnc({title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}); +} + +function AdvancedMultiSelect(props) { + const [masterCheckbox, setMasterCheckbox] = useState(true); + const { + schema, + id, + options, + value, + required, + disabled, + readonly, + multiple, + autofocus, + onChange, + registry + } = props; + const {enumOptions, defaultPaneParams} = options; + const [infoPaneParams, setInfoPaneParams] = useState(defaultPaneParams); + const selectValue = cloneDeep(value); + return ( +
+ + + {props.schema.title} + + + {enumOptions.map(({value, label}, i) => { + return ( + setPaneInfo(schema.items.$ref, registry, value, setInfoPaneParams)}> + + + {label} + + + ); + })} + + +
+ ); +} + +export default AdvancedMultiSelect; diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js deleted file mode 100644 index 70e0953a0..000000000 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultipleSelect.js +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react"; -import Button from 'react-bootstrap/Button'; - - -function ArrayFieldTemplate(props) { - return ( -
- {props.items && - props.items.map(element => ( -
-
{element.children}
- {element.hasMoveDown && ( - - )} - {element.hasMoveUp && ( - - )} - -
-
- ))} - - {props.canAdd && ( -
-

- -

-
- )} -
- ); -} - -export default ArrayFieldTemplate; diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js b/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js new file mode 100644 index 000000000..cd3315428 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js @@ -0,0 +1,52 @@ +import {Card, Button} from 'react-bootstrap'; +import React from 'react'; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; +import {faQuestionCircle} from "@fortawesome/free-solid-svg-icons"; + + +function InfoPane(props) { + return ( + + {getTitle(props)} + {getSubtitle(props)} + {getBody(props)} + ); +} + +function getTitle(props) { + if (typeof (props.title) == 'string') { + return ( + + {props.title} + {getLinkButton(props)} + ) + } +} + +function getLinkButton(props) { + if (typeof (props.link) == 'string') { + return ( + ) + } +} + +function getSubtitle(props) { + if (typeof (props.subtitle) == 'string') { + return ( + + {props.subtitle} + ) + } +} + +function getBody(props) { + return ( + + {props.body} + + ) +} + +export default InfoPane diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js new file mode 100644 index 000000000..208fc5398 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js @@ -0,0 +1,16 @@ +const defaultMinHeight = 50 +const defaultMaxHeight = 300 +const defaultSubcomponentHeight = 15 + +export function getComponentHeight(subcomponentCount, + subcomponentHeight = defaultSubcomponentHeight, + minHeight = defaultMinHeight, + maxHeight = defaultMaxHeight) { + let height = subcomponentHeight * subcomponentCount; + if (height > maxHeight) + height = maxHeight + else if (height < minHeight) + height = minHeight + + return height +} diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/ObjectPathResolver.js b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/ObjectPathResolver.js new file mode 100644 index 000000000..9fef26c7a --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/ObjectPathResolver.js @@ -0,0 +1,11 @@ + +// Resolves object's path if it's specified in a dot notation. +// (e.g. params: "firstLevel.secondLevel.property", myObject) +export function resolveObjectPath(pathArray, obj) { + return pathArray.reduce(function(prev, curr) { + if(curr === '') + return prev; + else + return prev ? prev[curr] : null; + }, obj || self) +} diff --git a/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss b/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss new file mode 100644 index 000000000..5cde76e3b --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss @@ -0,0 +1,47 @@ +.advanced-multi-select .choice-block.form-control { + overflow: scroll; + overflow-x: hidden; + padding: 0; + margin-left: 0; +} + +.advanced-multi-select svg { + font-size: 1.15em; +} + +.advanced-multi-select .card-header { + border: 1px solid $gray-300; + border-bottom: none; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + padding-left: 0; + padding-bottom: 5px; +} + +.advanced-multi-select .card-header button { + padding-top: 0; +} + +.advanced-multi-select .card-header .header-title { + font-size: 1.2em; +} + +.advanced-multi-select .choice-block .form-group { + margin: 0; + padding: 3px 0 0 0; + height: 30px; +} + +.advanced-multi-select .choice-block .form-group:hover { + background-color: $gray-300; + cursor: pointer; +} + +.advanced-multi-select .choice-block .form-group button { + margin: 0 5px 3px 10px; + padding: 0; +} + +.advanced-multi-select .option-text { + margin-left: 10px; +} diff --git a/monkey/monkey_island/cc/ui/src/styles/components/InfoPane.scss b/monkey/monkey_island/cc/ui/src/styles/components/InfoPane.scss new file mode 100644 index 000000000..8c61d873f --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/styles/components/InfoPane.scss @@ -0,0 +1,29 @@ +.info-pane, .card { + margin-top: 5px; +} + +.info-pane svg { + font-size: 1.1em; +} + +.info-pane .pane-title { + margin: 10px 15px 3px 15px; + color: $monkey-alt; +} + +.info-pane .pane-link { + position: absolute; + right: 0; + top: 0; +} + +.info-pane .pane-subtitle { + margin: 0 15px; + color: $gray-600; +} + + +.info-pane .pane-body { + margin: 10px 15px; + padding: 0; +} From fb9428b8a3c9218f4a9d8565df2254ecb963c76f Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 20 Jul 2020 15:10:57 +0300 Subject: [PATCH 06/40] Added advanced selector component to all config definitions, refactored it in a way that allows to define all advanced selector properties on config_schema.py --- .../cc/services/config_schema.py | 41 +++++++++++++++---- .../configuration-components/UiSchema.js | 23 +++++++---- .../ui-components/AdvancedMultiSelect.js | 17 ++++++-- .../ui-components/utils/HeightCalculator.js | 10 ++--- .../components/AdvancedMultiSelect.scss | 2 +- 5 files changed, 67 insertions(+), 26 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index b8f2701c0..f15cb639c 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -9,6 +9,7 @@ SCHEMA = { "definitions": { "exploiter_classes": { "title": "Exploit class", + "description": "Click on exploiter to get more information about it.", "type": "string", "anyOf": [ { @@ -70,7 +71,8 @@ SCHEMA = { "ShellShockExploiter" ], "title": "ShellShock Exploiter", - "info": "CVE-2014-6271, based on logic in NCC group's github.", + "info": "CVE-2014-6271, based on logic from " + "https://github.com/nccgroup/shocker/blob/master/shocker.py .", "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { @@ -97,7 +99,8 @@ SCHEMA = { "Struts2Exploiter" ], "title": "Struts2 Exploiter", - "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on this PoC.", + "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on " + "https://www.exploit-db.com/exploits/41570 .", "link": "https://github.com/guardicore/monkey/wiki/Exploiters" }, { @@ -133,6 +136,7 @@ SCHEMA = { }, "system_info_collectors_classes": { "title": "System Information Collectors", + "description": "Click on a system info collector to find out what it collects.", "type": "string", "anyOf": [ { @@ -140,7 +144,8 @@ SCHEMA = { "enum": [ ENVIRONMENT_COLLECTOR ], - "title": "Collect which environment this machine is on (on prem/cloud)", + "title": "Environment collector", + "info": "Collects information about machine's environment (on premise/GCP/AWS).", "attack_techniques": [] }, { @@ -148,7 +153,8 @@ SCHEMA = { "enum": [ AWS_COLLECTOR ], - "title": "If on AWS, collect more information about the instance", + "title": "AWS collector", + "info": "If on AWS, collects more information about the AWS instance currently running on.", "attack_techniques": [] }, { @@ -156,7 +162,8 @@ SCHEMA = { "enum": [ HOSTNAME_COLLECTOR ], - "title": "Collect the machine's hostname", + "title": "Hostname collector", + "info": "Collects machine's hostname.", "attack_techniques": [] }, { @@ -164,13 +171,16 @@ SCHEMA = { "enum": [ PROCESS_LIST_COLLECTOR ], - "title": "Collect running processes on the machine", + "title": "Process list collector", + "info": "Collects a list of running processes on the machine.", "attack_techniques": [] }, ], }, "post_breach_actions": { "title": "Post breach actions", + "description": "Runs scripts/commands on infected machines. These actions safely simulate what an adversary" + "might do after breaching a new machine. Used in ATT&CK and Zero trust reports.", "type": "string", "anyOf": [ { @@ -179,6 +189,7 @@ SCHEMA = { "BackdoorUser" ], "title": "Back door user", + "info": "Attempts to create a new user on the system and delete it afterwards.", "attack_techniques": ["T1136"] }, { @@ -187,6 +198,8 @@ SCHEMA = { "CommunicateAsNewUser" ], "title": "Communicate as new user", + "info": "Attempts to create a new user, create HTTPS requests as that user and delete the user " + "afterwards.", "attack_techniques": ["T1136"] }, { @@ -195,6 +208,8 @@ SCHEMA = { "ModifyShellStartupFiles" ], "title": "Modify shell startup files", + "info": "Attempts to modify shell startup files, like ~/.profile, ~/.bashrc, ~/.bash_profile " + "in linux, and profile.ps1 in windows. Reverts modifications done afterwards.", "attack_techniques": ["T1156", "T1504"] }, { @@ -203,12 +218,15 @@ SCHEMA = { "HiddenFiles" ], "title": "Hidden files and directories", + "info": "Attempts to create a hidden file and remove it afterward.", "attack_techniques": ["T1158"] } ], }, "finger_classes": { "title": "Fingerprint class", + "description": "Fingerprint modules collect info about external services " + "Infection Monkey scans.", "type": "string", "anyOf": [ { @@ -217,6 +235,7 @@ SCHEMA = { "SMBFinger" ], "title": "SMBFinger", + "info": "Figures out if SMB is running and what's the version of it.", "attack_techniques": ["T1210"] }, { @@ -225,6 +244,7 @@ SCHEMA = { "SSHFinger" ], "title": "SSHFinger", + "info": "Figures out if SSH is running.", "attack_techniques": ["T1210"] }, { @@ -232,14 +252,16 @@ SCHEMA = { "enum": [ "PingScanner" ], - "title": "PingScanner" + "title": "PingScanner", + "info": "Tries to identify if host is alive and which OS it's running by ping scan." }, { "type": "string", "enum": [ "HTTPFinger" ], - "title": "HTTPFinger" + "title": "HTTPFinger", + "info": "Checks if host has HTTP/HTTPS ports open." }, { "type": "string", @@ -247,6 +269,7 @@ SCHEMA = { "MySQLFinger" ], "title": "MySQLFinger", + "info": "Checks if MySQL server is running and tries to get it's version.", "attack_techniques": ["T1210"] }, { @@ -255,6 +278,7 @@ SCHEMA = { "MSSQLFinger" ], "title": "MSSQLFinger", + "info": "Checks if Microsoft SQL service is running and tries to gather information about it.", "attack_techniques": ["T1210"] }, @@ -264,6 +288,7 @@ SCHEMA = { "ElasticFinger" ], "title": "ElasticFinger", + "info": "Checks if ElasticSearch is running and attempts to find it's version.", "attack_techniques": ["T1210"] } ] diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 7b7d2bfcb..0552700f5 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -9,6 +9,11 @@ export default function UiSchema(props) { }, basic_network: {}, monkey: { + general: { + post_breach_actions: { + 'ui:widget': AdvancedMultiSelect + } + }, behaviour: { custom_PBA_linux_cmd: { 'ui:widget': 'textarea', @@ -42,6 +47,11 @@ export default function UiSchema(props) { classNames: 'windows-pba-file-info', 'ui:emptyValue': '' } + }, + system_info: { + system_info_collectors_classes: { + 'ui:widget': AdvancedMultiSelect + } } }, cnc: {}, @@ -49,19 +59,18 @@ export default function UiSchema(props) { exploits: { general: { exploiter_classes: { - 'ui:widget': AdvancedMultiSelect, - 'ui:options': { - defaultPaneParams: { - title: 'Exploiters', - content: 'Click on exploiter to get more information about it.' - } - } + 'ui:widget': AdvancedMultiSelect } } }, internal: { general: { started_on_island: {'ui:widget': 'hidden'} + }, + classes: { + finger_classes: { + 'ui:widget': AdvancedMultiSelect + } } } } diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js index f8083060b..03b4935f2 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js @@ -32,9 +32,12 @@ function onMasterCheckboxClick(checkboxValue, defaultArray, onChangeFnc) { // Definitions passed to components only contains value and label, // custom fields like "info" or "links" must be pulled from registry object using this function function getFullDefinitionsFromRegistry(refString, registry) { + return getObjectFromRegistryByRef(refString, registry).anyOf; +} + +function getObjectFromRegistryByRef(refString, registry) { let refArray = refString.replace('#', '').split('/'); - let definitionObject = resolveObjectPath(refArray, registry); - return definitionObject.anyOf; + return resolveObjectPath(refArray, registry); } function getFullDefinitionByKey(refString, registry, itemKey) { @@ -47,6 +50,11 @@ function setPaneInfo(refString, registry, itemKey, setPaneInfoFnc) { setPaneInfoFnc({title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}); } +function getDefaultPaneParams(refString, registry){ + let configSection = getObjectFromRegistryByRef(refString, registry); + return ({title: configSection.title, content: configSection.description}); +} + function AdvancedMultiSelect(props) { const [masterCheckbox, setMasterCheckbox] = useState(true); const { @@ -62,8 +70,9 @@ function AdvancedMultiSelect(props) { onChange, registry } = props; - const {enumOptions, defaultPaneParams} = options; - const [infoPaneParams, setInfoPaneParams] = useState(defaultPaneParams); + const {enumOptions} = options; + const [infoPaneParams, setInfoPaneParams] = useState(getDefaultPaneParams(schema.items.$ref, registry)); + getDefaultPaneParams(schema.items.$ref, registry); const selectValue = cloneDeep(value); return (
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js index 208fc5398..1dcd47516 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js @@ -1,16 +1,14 @@ -const defaultMinHeight = 50 -const defaultMaxHeight = 300 -const defaultSubcomponentHeight = 15 +const defaultMinHeight = 25 +const defaultMaxHeight = 250 +const defaultSubcomponentHeight = 25 export function getComponentHeight(subcomponentCount, subcomponentHeight = defaultSubcomponentHeight, minHeight = defaultMinHeight, maxHeight = defaultMaxHeight) { - let height = subcomponentHeight * subcomponentCount; + let height = defaultMinHeight + (subcomponentHeight*subcomponentCount); if (height > maxHeight) height = maxHeight - else if (height < minHeight) - height = minHeight return height } diff --git a/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss b/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss index 5cde76e3b..3dc1fe9a5 100644 --- a/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss +++ b/monkey/monkey_island/cc/ui/src/styles/components/AdvancedMultiSelect.scss @@ -38,7 +38,7 @@ } .advanced-multi-select .choice-block .form-group button { - margin: 0 5px 3px 10px; + margin: 0 3px 3px 12px; padding: 0; } From 35e90fc95d0d9013e06f1dc5ca2199653acbd6b5 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 20 Jul 2020 15:22:21 +0300 Subject: [PATCH 07/40] Added style that allows hiding config input component title and description (because advanced multi select has title and description built in) --- .../src/components/configuration-components/UiSchema.js | 4 ++++ .../cc/ui/src/styles/pages/ConfigurationPage.scss | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 0552700f5..1e06b479a 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -11,6 +11,7 @@ export default function UiSchema(props) { monkey: { general: { post_breach_actions: { + classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } }, @@ -50,6 +51,7 @@ export default function UiSchema(props) { }, system_info: { system_info_collectors_classes: { + classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } } @@ -59,6 +61,7 @@ export default function UiSchema(props) { exploits: { general: { exploiter_classes: { + classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } } @@ -69,6 +72,7 @@ export default function UiSchema(props) { }, classes: { finger_classes: { + classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } } diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index 09e15e3ad..8dd01f614 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -25,3 +25,11 @@ .config-form .form-group { margin-left: 2em; } + +.config-template-no-header>p{ + display: none; +} + +.config-template-no-header>label{ + display: none; +} From f790750f578ef7829120a84192655fc9da619223 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 20 Jul 2020 17:15:01 +0300 Subject: [PATCH 08/40] Changed the style in configuration page to differentiate config value title from description --- .../cc/ui/src/styles/pages/ConfigurationPage.scss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index 8dd01f614..20e862d0d 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -26,10 +26,16 @@ margin-left: 2em; } -.config-template-no-header>p{ +.config-template-no-header > p { display: none; } -.config-template-no-header>label{ +.config-template-no-header > label { display: none; } + +.config-form .form-group.field > label { + margin-top: 10px; + margin-bottom: 5px; + font-size: 1.2em; +} From 167d1f50d5f7dba24623776c5b5544ee2cc90aca Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 20 Jul 2020 17:32:08 +0300 Subject: [PATCH 09/40] Removed hidden descriptions --- .../monkey_island/cc/services/config_schema.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 6a02fd45e..5d1161789 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -11,7 +11,8 @@ SCHEMA = { "definitions": { "exploiter_classes": { "title": "Exploit class", - "description": "Click on exploiter to get more information about it.", + "description": "Click on exploiter to get more information about it." + WARNING_SIGN + + " Note that using unsafe exploits may cause crashes of the exploited machine/service.", "type": "string", "anyOf": [ { @@ -481,8 +482,7 @@ SCHEMA = { "TrapCommand", "ChangeSetuidSetgid", "ScheduleJobs" - ], - "description": "List of actions the Monkey will run post breach" + ] }, } }, @@ -588,8 +588,7 @@ SCHEMA = { AWS_COLLECTOR, HOSTNAME_COLLECTOR, PROCESS_LIST_COLLECTOR - ], - "description": "Determines which system information collectors will collect information." + ] }, } }, @@ -693,8 +692,7 @@ SCHEMA = { "MySQLFinger", "MSSQLFinger", "ElasticFinger" - ], - "description": "Determines which classes to use for fingerprinting" + ] } } }, @@ -933,10 +931,7 @@ SCHEMA = { "HadoopExploiter", "VSFTPDExploiter", "MSSQLExploiter" - ], - "description": - "Determines which exploits to use. " + WARNING_SIGN - + " Note that using unsafe exploits may cause crashes of the exploited machine/service" + ] }, "skip_exploit_if_file_exist": { "title": "Skip exploit if file exists", From 9f21ce07f1d4e9d25604018dab3c87d518bb51c9 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 20 Jul 2020 18:22:37 +0300 Subject: [PATCH 10/40] Changed important tabs to be highlighted rather than having text in the front --- monkey/monkey_island/cc/services/config_schema.py | 5 +++-- .../cc/ui/src/components/pages/ConfigurePage.js | 9 ++++++--- .../cc/ui/src/styles/pages/ConfigurationPage.scss | 5 +++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 5d1161789..4915fe066 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -323,8 +323,9 @@ SCHEMA = { }, "properties": { "basic": { - "title": "Basic - Exploits", + "title": "Exploits", "type": "object", + "primary": True, "properties": { "general": { "title": "General", @@ -377,7 +378,7 @@ SCHEMA = { } }, "basic_network": { - "title": "Basic - Network", + "title": "Network", "type": "object", "properties": { "general": { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index e75978b7f..e2042fa69 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -383,10 +383,13 @@ class ConfigurePageComponent extends AuthComponent { activeKey={this.state.selectedSection} onSelect={this.setSelectedSection} style={{'marginBottom': '2em'}} className={'config-nav'}> - {this.state.sections.map(section => + {this.state.sections.map(section => { + let classProp = section.key.startsWith('basic') ? 'tab-primary' : ''; + return ( - {section.title} - )} + {section.title} + ); + })} ) }; diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index 20e862d0d..c8f710d32 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -2,6 +2,11 @@ height: 50px !important; } +.config-nav .nav-link.tab-primary{ + color: $monkey-alt; + font-weight: bold; +} + .config-nav .nav-item > a{ color: $black; padding: 15px 10px 15px 10px; From f70b2240e1cc2947dc824ec855ea237e4594c875 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 21 Jul 2020 10:43:37 +0300 Subject: [PATCH 11/40] Hid "Is monkey alive" field in configuration --- .../cc/ui/src/components/configuration-components/UiSchema.js | 3 +++ .../cc/ui/src/styles/pages/ConfigurationPage.scss | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 1e06b479a..f28393d1d 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -10,6 +10,9 @@ export default function UiSchema(props) { basic_network: {}, monkey: { general: { + alive: { + classNames: 'config-field-hidden' + }, post_breach_actions: { classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index c8f710d32..48b168476 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -44,3 +44,7 @@ margin-bottom: 5px; font-size: 1.2em; } + +.config-field-hidden { + display: none; +} From eb4056ab7fec392c1e41270dc59cdf2a05439535 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 21 Jul 2020 11:29:29 +0300 Subject: [PATCH 12/40] Removed should exploit network machines config param - same will be achieved by removing all exploiters. --- monkey/infection_monkey/monkey.py | 21 +++++++++---------- .../cc/services/config_schema.py | 7 ------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index ec63fd6a8..e01338a48 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -196,17 +196,16 @@ class InfectionMonkey(object): LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server)) # Order exploits according to their type - if WormConfiguration.should_exploit: - self._exploiters = sorted(self._exploiters, key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value) - host_exploited = False - for exploiter in [exploiter(machine) for exploiter in self._exploiters]: - if self.try_exploiting(machine, exploiter): - host_exploited = True - VictimHostTelem('T1210', ScanStatus.USED, machine=machine).send() - break - if not host_exploited: - self._fail_exploitation_machines.add(machine) - VictimHostTelem('T1210', ScanStatus.SCANNED, machine=machine).send() + self._exploiters = sorted(self._exploiters, key=lambda exploiter_: exploiter_.EXPLOIT_TYPE.value) + host_exploited = False + for exploiter in [exploiter(machine) for exploiter in self._exploiters]: + if self.try_exploiting(machine, exploiter): + host_exploited = True + VictimHostTelem('T1210', ScanStatus.USED, machine=machine).send() + break + if not host_exploited: + self._fail_exploitation_machines.add(machine) + VictimHostTelem('T1210', ScanStatus.SCANNED, machine=machine).send() if not self._keep_running: break diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 4915fe066..769091e81 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -331,13 +331,6 @@ SCHEMA = { "title": "General", "type": "object", "properties": { - "should_exploit": { - "title": "Exploit network machines", - "type": "boolean", - "default": True, - "attack_techniques": ["T1210"], - "description": "Determines if monkey should try to safely exploit machines on the network" - } } }, "credentials": { From 3fec6ac753c7399797f541883f5011307aedbc6d Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 22 Jul 2020 12:33:21 +0300 Subject: [PATCH 13/40] Renamed values in config: Network->General to Network->Scope, Exploits->General to Exploits->Exploiters --- .../cc/services/config_schema.py | 50 +++++++++---------- .../cc/services/reporting/report.py | 6 +-- .../configuration-components/UiSchema.js | 16 +++--- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py index 769091e81..07e9e9cb9 100644 --- a/monkey/monkey_island/cc/services/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema.py @@ -327,10 +327,31 @@ SCHEMA = { "type": "object", "primary": True, "properties": { - "general": { - "title": "General", + "exploiters": { + "title": "Exploiters", "type": "object", "properties": { + "exploiter_classes": { + "title": "Exploiters", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/exploiter_classes" + }, + "default": [ + "SmbExploiter", + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter", + "MSSQLExploiter" + ] + } } }, "credentials": { @@ -374,8 +395,8 @@ SCHEMA = { "title": "Network", "type": "object", "properties": { - "general": { - "title": "General", + "scope": { + "title": "Scope", "type": "object", "properties": { "blocked_ips": { @@ -906,27 +927,6 @@ SCHEMA = { "title": "General", "type": "object", "properties": { - "exploiter_classes": { - "title": "Exploits", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/exploiter_classes" - }, - "default": [ - "SmbExploiter", - "WmiExploiter", - "SSHExploiter", - "ShellShockExploiter", - "SambaCryExploiter", - "ElasticGroovyExploiter", - "Struts2Exploiter", - "WebLogicExploiter", - "HadoopExploiter", - "VSFTPDExploiter", - "MSSQLExploiter" - ] - }, "skip_exploit_if_file_exist": { "title": "Skip exploit if file exists", "type": "boolean", diff --git a/monkey/monkey_island/cc/services/reporting/report.py b/monkey/monkey_island/cc/services/reporting/report.py index 9880b0ed0..f557c6a01 100644 --- a/monkey/monkey_island/cc/services/reporting/report.py +++ b/monkey/monkey_island/cc/services/reporting/report.py @@ -618,7 +618,7 @@ class ReportService: @staticmethod def get_config_exploits(): - exploits_config_value = ['exploits', 'general', 'exploiter_classes'] + exploits_config_value = ['basic', 'exploiters', 'exploiter_classes'] default_exploits = ConfigService.get_default_config(False) for namespace in exploits_config_value: default_exploits = default_exploits[namespace] @@ -632,11 +632,11 @@ class ReportService: @staticmethod def get_config_ips(): - return ConfigService.get_config_value(['basic_network', 'general', 'subnet_scan_list'], True, True) + return ConfigService.get_config_value(['basic_network', 'scope', 'subnet_scan_list'], True, True) @staticmethod def get_config_scan(): - return ConfigService.get_config_value(['basic_network', 'general', 'local_network_scan'], True, True) + return ConfigService.get_config_value(['basic_network', 'scope', 'local_network_scan'], True, True) @staticmethod def get_issues_overview(issues, config_users, config_passwords): diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index f28393d1d..3b1e233d8 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -5,7 +5,13 @@ import {API_PBA_LINUX, API_PBA_WINDOWS} from '../pages/ConfigurePage'; export default function UiSchema(props) { const UiSchema = { basic: { - 'ui:order': ['general', 'credentials'], + 'ui:order': ['exploiters', 'credentials'], + exploiters: { + exploiter_classes: { + classNames: 'config-template-no-header', + 'ui:widget': AdvancedMultiSelect + } + } }, basic_network: {}, monkey: { @@ -61,14 +67,6 @@ export default function UiSchema(props) { }, cnc: {}, network: {}, - exploits: { - general: { - exploiter_classes: { - classNames: 'config-template-no-header', - 'ui:widget': AdvancedMultiSelect - } - } - }, internal: { general: { started_on_island: {'ui:widget': 'hidden'} From 8b2797306bf86a925660eb0427bc51a9bf4e9b25 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 22 Jul 2020 13:19:12 +0300 Subject: [PATCH 14/40] Split up config_schema.py into separate files --- monkey/infection_monkey/config.py | 2 +- .../system_info/system_info_collector.py | 2 +- monkey/monkey_island/cc/services/config.py | 2 +- .../cc/services/config_schema.py | 1113 ----------------- .../cc/services/config_schema/__init__.py | 0 .../cc/services/config_schema/basic.py | 69 + .../services/config_schema/basic_network.py | 79 ++ .../cc/services/config_schema/cnc.py | 45 + .../services/config_schema/config_schema.py | 36 + .../definitions/exploiter_classes.py | 130 ++ .../definitions/finger_classes.py | 70 ++ .../definitions/post_breach_actions.py | 70 ++ .../system_info_collector_classes.py | 48 + .../cc/services/config_schema/exploits.py | 105 ++ .../cc/services/config_schema/internal.py | 222 ++++ .../cc/services/config_schema/monkey.py | 190 +++ .../cc/services/config_schema/network.py | 82 ++ .../cc/services/utils/__init__.py | 0 .../cc/services/utils/typographic_symbols.py | 1 + .../configuration-components/UiSchema.js | 2 +- 20 files changed, 1151 insertions(+), 1117 deletions(-) delete mode 100644 monkey/monkey_island/cc/services/config_schema.py create mode 100644 monkey/monkey_island/cc/services/config_schema/__init__.py create mode 100644 monkey/monkey_island/cc/services/config_schema/basic.py create mode 100644 monkey/monkey_island/cc/services/config_schema/basic_network.py create mode 100644 monkey/monkey_island/cc/services/config_schema/cnc.py create mode 100644 monkey/monkey_island/cc/services/config_schema/config_schema.py create mode 100644 monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py create mode 100644 monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py create mode 100644 monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py create mode 100644 monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py create mode 100644 monkey/monkey_island/cc/services/config_schema/exploits.py create mode 100644 monkey/monkey_island/cc/services/config_schema/internal.py create mode 100644 monkey/monkey_island/cc/services/config_schema/monkey.py create mode 100644 monkey/monkey_island/cc/services/config_schema/network.py create mode 100644 monkey/monkey_island/cc/services/utils/__init__.py create mode 100644 monkey/monkey_island/cc/services/utils/typographic_symbols.py diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 910b0abd7..0413bdcd3 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -129,7 +129,7 @@ class Configuration(object): finger_classes = [] exploiter_classes = [] - system_info_collectors_classes = [] + system_info_collector_classes = [] # how many victims to look for in a single scan iteration victims_max_find = 100 diff --git a/monkey/infection_monkey/system_info/system_info_collector.py b/monkey/infection_monkey/system_info/system_info_collector.py index a16560930..ee4bb21e8 100644 --- a/monkey/infection_monkey/system_info/system_info_collector.py +++ b/monkey/infection_monkey/system_info/system_info_collector.py @@ -19,7 +19,7 @@ class SystemInfoCollector(Plugin, metaclass=ABCMeta): @staticmethod def should_run(class_name) -> bool: - return class_name in WormConfiguration.system_info_collectors_classes + return class_name in WormConfiguration.system_info_collector_classes @staticmethod def base_package_file(): diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index e8453a052..5b6c4529b 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -11,7 +11,7 @@ from monkey_island.cc.database import mongo from monkey_island.cc.encryptor import encryptor from monkey_island.cc.network_utils import local_ip_addresses -from .config_schema import SCHEMA +from monkey_island.cc.services.config_schema.config_schema import SCHEMA __author__ = "itay.mizeretz" diff --git a/monkey/monkey_island/cc/services/config_schema.py b/monkey/monkey_island/cc/services/config_schema.py deleted file mode 100644 index 07e9e9cb9..000000000 --- a/monkey/monkey_island/cc/services/config_schema.py +++ /dev/null @@ -1,1113 +0,0 @@ -from common.data.system_info_collectors_names import (AWS_COLLECTOR, - ENVIRONMENT_COLLECTOR, - HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR) - -WARNING_SIGN = " \u26A0" - -SCHEMA = { - "title": "Monkey", - "type": "object", - "definitions": { - "exploiter_classes": { - "title": "Exploit class", - "description": "Click on exploiter to get more information about it." + WARNING_SIGN + - " Note that using unsafe exploits may cause crashes of the exploited machine/service.", - "type": "string", - "anyOf": [ - { - "type": "string", - "enum": [ - "SmbExploiter" - ], - "title": "SMB Exploiter", - "attack_techniques": ["T1110", "T1075", "T1035"], - "info": "Brute forces using credentials provided by user and" - " hashes gathered by mimikatz.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "WmiExploiter" - ], - "title": "WMI Exploiter", - "attack_techniques": ["T1110", "T1106"], - "info": "Brute forces WMI (Windows Management Instrumentation) " - "using credentials provided by user and hashes gathered by mimikatz.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "MSSQLExploiter" - ], - "title": "MSSQL Exploiter", - "attack_techniques": ["T1110"], - "info": "Tries to brute force into MsSQL server and uses insecure " - "configuration to execute commands on server.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "Ms08_067_Exploiter" - ], - "title": "MS08-067 Exploiter (UNSAFE)", - "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. " - "Uses MS08-067 vulnerability.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "SSHExploiter" - ], - "title": "SSH Exploiter", - "attack_techniques": ["T1110", "T1145", "T1106"], - "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "ShellShockExploiter" - ], - "title": "ShellShock Exploiter", - "info": "CVE-2014-6271, based on logic from " - "https://github.com/nccgroup/shocker/blob/master/shocker.py .", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "SambaCryExploiter" - ], - "title": "SambaCry Exploiter", - "info": "Bruteforces and searches for anonymous shares. Uses Impacket.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "ElasticGroovyExploiter" - ], - "title": "ElasticGroovy Exploiter", - "info": "CVE-2015-1427. Logic is based on Metasploit module.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "Struts2Exploiter" - ], - "title": "Struts2 Exploiter", - "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on " - "https://www.exploit-db.com/exploits/41570 .", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "WebLogicExploiter" - ], - "title": "WebLogic Exploiter", - "info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "HadoopExploiter" - ], - "title": "Hadoop/Yarn Exploiter", - "info": "Remote code execution on HADOOP server with YARN and default settings. " - "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - }, - { - "type": "string", - "enum": [ - "VSFTPDExploiter" - ], - "title": "VSFTPD Exploiter", - "info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. " - "Logic based on Metasploit module.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" - } - ] - }, - "system_info_collectors_classes": { - "title": "System Information Collectors", - "description": "Click on a system info collector to find out what it collects.", - "type": "string", - "anyOf": [ - { - "type": "string", - "enum": [ - ENVIRONMENT_COLLECTOR - ], - "title": "Environment collector", - "info": "Collects information about machine's environment (on premise/GCP/AWS).", - "attack_techniques": [] - }, - { - "type": "string", - "enum": [ - AWS_COLLECTOR - ], - "title": "AWS collector", - "info": "If on AWS, collects more information about the AWS instance currently running on.", - "attack_techniques": [] - }, - { - "type": "string", - "enum": [ - HOSTNAME_COLLECTOR - ], - "title": "Hostname collector", - "info": "Collects machine's hostname.", - "attack_techniques": [] - }, - { - "type": "string", - "enum": [ - PROCESS_LIST_COLLECTOR - ], - "title": "Process list collector", - "info": "Collects a list of running processes on the machine.", - "attack_techniques": [] - }, - ], - }, - "post_breach_actions": { - "title": "Post breach actions", - "description": "Runs scripts/commands on infected machines. These actions safely simulate what an adversary" - "might do after breaching a new machine. Used in ATT&CK and Zero trust reports.", - "type": "string", - "anyOf": [ - { - "type": "string", - "enum": [ - "BackdoorUser" - ], - "title": "Back door user", - "info": "Attempts to create a new user on the system and delete it afterwards.", - "attack_techniques": ["T1136"] - }, - { - "type": "string", - "enum": [ - "CommunicateAsNewUser" - ], - "title": "Communicate as new user", - "info": "Attempts to create a new user, create HTTPS requests as that user and delete the user " - "afterwards.", - "attack_techniques": ["T1136"] - }, - { - "type": "string", - "enum": [ - "ModifyShellStartupFiles" - ], - "title": "Modify shell startup files", - "info": "Attempts to modify shell startup files, like ~/.profile, ~/.bashrc, ~/.bash_profile " - "in linux, and profile.ps1 in windows. Reverts modifications done afterwards.", - "attack_techniques": ["T1156", "T1504"] - }, - { - "type": "string", - "enum": [ - "HiddenFiles" - ], - "title": "Hidden files and directories", - "info": "Attempts to create a hidden file and remove it afterward.", - "attack_techniques": ["T1158"] - }, - { - "type": "string", - "enum": [ - "TrapCommand" - ], - "title": "Trap", - "attack_techniques": ["T1154"] - }, - { - "type": "string", - "enum": [ - "ChangeSetuidSetgid" - ], - "title": "Setuid and Setgid", - "attack_techniques": ["T1166"] - }, - { - "type": "string", - "enum": [ - "ScheduleJobs" - ], - "title": "Job scheduling", - "attack_techniques": ["T1168", "T1053"] - } - ], - }, - "finger_classes": { - "title": "Fingerprint class", - "description": "Fingerprint modules collect info about external services " - "Infection Monkey scans.", - "type": "string", - "anyOf": [ - { - "type": "string", - "enum": [ - "SMBFinger" - ], - "title": "SMBFinger", - "info": "Figures out if SMB is running and what's the version of it.", - "attack_techniques": ["T1210"] - }, - { - "type": "string", - "enum": [ - "SSHFinger" - ], - "title": "SSHFinger", - "info": "Figures out if SSH is running.", - "attack_techniques": ["T1210"] - }, - { - "type": "string", - "enum": [ - "PingScanner" - ], - "title": "PingScanner", - "info": "Tries to identify if host is alive and which OS it's running by ping scan." - }, - { - "type": "string", - "enum": [ - "HTTPFinger" - ], - "title": "HTTPFinger", - "info": "Checks if host has HTTP/HTTPS ports open." - }, - { - "type": "string", - "enum": [ - "MySQLFinger" - ], - "title": "MySQLFinger", - "info": "Checks if MySQL server is running and tries to get it's version.", - "attack_techniques": ["T1210"] - }, - { - "type": "string", - "enum": [ - "MSSQLFinger" - ], - "title": "MSSQLFinger", - "info": "Checks if Microsoft SQL service is running and tries to gather information about it.", - "attack_techniques": ["T1210"] - }, - - { - "type": "string", - "enum": [ - "ElasticFinger" - ], - "title": "ElasticFinger", - "info": "Checks if ElasticSearch is running and attempts to find it's version.", - "attack_techniques": ["T1210"] - } - ] - } - }, - "properties": { - "basic": { - "title": "Exploits", - "type": "object", - "primary": True, - "properties": { - "exploiters": { - "title": "Exploiters", - "type": "object", - "properties": { - "exploiter_classes": { - "title": "Exploiters", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/exploiter_classes" - }, - "default": [ - "SmbExploiter", - "WmiExploiter", - "SSHExploiter", - "ShellShockExploiter", - "SambaCryExploiter", - "ElasticGroovyExploiter", - "Struts2Exploiter", - "WebLogicExploiter", - "HadoopExploiter", - "VSFTPDExploiter", - "MSSQLExploiter" - ] - } - } - }, - "credentials": { - "title": "Credentials", - "type": "object", - "properties": { - "exploit_user_list": { - "title": "Exploit user list", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "Administrator", - "root", - "user" - ], - "description": "List of usernames to use on exploits using credentials" - }, - "exploit_password_list": { - "title": "Exploit password list", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "Password1!", - "1234", - "password", - "12345678" - ], - "description": "List of password to use on exploits using credentials" - } - } - } - } - }, - "basic_network": { - "title": "Network", - "type": "object", - "properties": { - "scope": { - "title": "Scope", - "type": "object", - "properties": { - "blocked_ips": { - "title": "Blocked IPs", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - ], - "description": "List of IPs to not scan" - }, - "local_network_scan": { - "title": "Local network scan", - "type": "boolean", - "default": True, - "description": "Determines whether the monkey should scan its subnets additionally" - }, - "depth": { - "title": "Distance from island", - "type": "integer", - "default": 2, - "description": - "Amount of hops allowed for the monkey to spread from the island. " - + WARNING_SIGN - + " Note that setting this value too high may result in the monkey propagating too far" - }, - "subnet_scan_list": { - "title": "Scan IP/subnet list", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - ], - "description": - "List of IPs/subnets/hosts the monkey should scan." - " Examples: \"192.168.0.1\", \"192.168.0.5-192.168.0.20\", \"192.168.0.5/24\"," - " \"printer.example\"" - } - } - }, - "network_analysis": { - "title": "Network Analysis", - "type": "object", - "properties": { - "inaccessible_subnets": { - "title": "Network segmentation testing", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - ], - "description": - "Test for network segmentation by providing a list of" - " subnets that should NOT be accessible to each other." - " For example, given the following configuration:" - " '10.0.0.0/24, 11.0.0.2/32, 12.2.3.0/24'" - " a Monkey running on 10.0.0.5 will try to access machines in the following" - " subnets: 11.0.0.2/32, 12.2.3.0/24." - " An alert on successful connections will be shown in the report" - " Additional subnet formats include: 13.0.0.1, 13.0.0.1-13.0.0.5" - } - } - } - } - }, - "monkey": { - "title": "Monkey", - "type": "object", - "properties": { - "general": { - "title": "General", - "type": "object", - "properties": { - "alive": { - "title": "Alive", - "type": "boolean", - "default": True, - "description": "Is the monkey alive" - }, - "post_breach_actions": { - "title": "Post breach actions", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/post_breach_actions" - }, - "default": [ - "BackdoorUser", - "CommunicateAsNewUser", - "ModifyShellStartupFiles", - "HiddenFiles", - "TrapCommand", - "ChangeSetuidSetgid", - "ScheduleJobs" - ] - }, - } - }, - "behaviour": { - "title": "Behaviour", - "type": "object", - "properties": { - "custom_PBA_linux_cmd": { - "title": "Linux post breach command", - "type": "string", - "default": "", - "description": "Linux command to be executed after breaching." - }, - "PBA_linux_file": { - "title": "Linux post breach file", - "type": "string", - "format": "data-url", - "description": "File to be executed after breaching. " - "If you want custom execution behavior, " - "specify it in 'Linux post breach command' field. " - "Reference your file by filename." - }, - "custom_PBA_windows_cmd": { - "title": "Windows post breach command", - "type": "string", - "default": "", - "description": "Windows command to be executed after breaching." - }, - "PBA_windows_file": { - "title": "Windows post breach file", - "type": "string", - "format": "data-url", - "description": "File to be executed after breaching. " - "If you want custom execution behavior, " - "specify it in 'Windows post breach command' field. " - "Reference your file by filename." - }, - "PBA_windows_filename": { - "title": "Windows PBA filename", - "type": "string", - "default": "" - }, - "PBA_linux_filename": { - "title": "Linux PBA filename", - "type": "string", - "default": "" - }, - "self_delete_in_cleanup": { - "title": "Self delete on cleanup", - "type": "boolean", - "default": True, - "description": "Should the monkey delete its executable when going down" - }, - "use_file_logging": { - "title": "Use file logging", - "type": "boolean", - "default": True, - "description": "Should the monkey dump to a log file" - }, - "serialize_config": { - "title": "Serialize config", - "type": "boolean", - "default": False, - "description": "Should the monkey dump its config on startup" - } - } - }, - "system_info": { - "title": "System info", - "type": "object", - "properties": { - "extract_azure_creds": { - "title": "Harvest Azure Credentials", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": - "Determine if the Monkey should try to harvest password credentials from Azure VMs" - }, - "collect_system_info": { - "title": "Collect system info", - "type": "boolean", - "default": True, - "attack_techniques": ["T1082", "T1005", "T1016"], - "description": "Determines whether to collect system info" - }, - "should_use_mimikatz": { - "title": "Should use Mimikatz", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": "Determines whether to use Mimikatz" - }, - "system_info_collectors_classes": { - "title": "System info collectors", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/system_info_collectors_classes" - }, - "default": [ - ENVIRONMENT_COLLECTOR, - AWS_COLLECTOR, - HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR - ] - }, - } - }, - "life_cycle": { - "title": "Life cycle", - "type": "object", - "properties": { - "max_iterations": { - "title": "Max iterations", - "type": "integer", - "default": 1, - "description": "Determines how many iterations of the monkey's full lifecycle should occur" - }, - "victims_max_find": { - "title": "Max victims to find", - "type": "integer", - "default": 100, - "description": "Determines the maximum number of machines the monkey is allowed to scan" - }, - "victims_max_exploit": { - "title": "Max victims to exploit", - "type": "integer", - "default": 15, - "description": - "Determines the maximum number of machines the monkey" - " is allowed to successfully exploit. " + WARNING_SIGN - + " Note that setting this value too high may result in the monkey propagating to " - "a high number of machines" - }, - "timeout_between_iterations": { - "title": "Wait time between iterations", - "type": "integer", - "default": 100, - "description": - "Determines for how long (in seconds) should the monkey wait between iterations" - }, - "retry_failed_explotation": { - "title": "Retry failed exploitation", - "type": "boolean", - "default": True, - "description": - "Determines whether the monkey should retry exploiting machines" - " it didn't successfully exploit on previous iterations" - } - } - } - } - }, - "internal": { - "title": "Internal", - "type": "object", - "properties": { - "general": { - "title": "General", - "type": "object", - "properties": { - "singleton_mutex_name": { - "title": "Singleton mutex name", - "type": "string", - "default": "{2384ec59-0df8-4ab9-918c-843740924a28}", - "description": - "The name of the mutex used to determine whether the monkey is already running" - }, - "keep_tunnel_open_time": { - "title": "Keep tunnel open time", - "type": "integer", - "default": 60, - "description": "Time to keep tunnel open before going down after last exploit (in seconds)" - }, - "monkey_dir_name": { - "title": "Monkey's directory name", - "type": "string", - "default": r"monkey_dir", - "description": "Directory name for the directory which will contain all of the monkey files" - }, - "started_on_island": { - "title": "Started on island", - "type": "boolean", - "default": False, - "description": "Was exploitation started from island" - "(did monkey with max depth ran on island)" - }, - } - }, - "classes": { - "title": "Classes", - "type": "object", - "properties": { - "finger_classes": { - "title": "Fingerprint classes", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/finger_classes" - }, - "default": [ - "SMBFinger", - "SSHFinger", - "PingScanner", - "HTTPFinger", - "MySQLFinger", - "MSSQLFinger", - "ElasticFinger" - ] - } - } - }, - "kill_file": { - "title": "Kill file", - "type": "object", - "properties": { - "kill_file_path_windows": { - "title": "Kill file path on Windows", - "type": "string", - "default": "%windir%\\monkey.not", - "description": "Path of file which kills monkey if it exists (on Windows)" - }, - "kill_file_path_linux": { - "title": "Kill file path on Linux", - "type": "string", - "default": "/var/run/monkey.not", - "description": "Path of file which kills monkey if it exists (on Linux)" - } - } - }, - "dropper": { - "title": "Dropper", - "type": "object", - "properties": { - "dropper_set_date": { - "title": "Dropper sets date", - "type": "boolean", - "default": True, - "description": - "Determines whether the dropper should set the monkey's file date to be the same as" - " another file" - }, - "dropper_date_reference_path_windows": { - "title": "Dropper date reference path (Windows)", - "type": "string", - "default": "%windir%\\system32\\kernel32.dll", - "description": - "Determines which file the dropper should copy the date from if it's configured to do" - " so on Windows (use fullpath)" - }, - "dropper_date_reference_path_linux": { - "title": "Dropper date reference path (Linux)", - "type": "string", - "default": "/bin/sh", - "description": - "Determines which file the dropper should copy the date from if it's configured to do" - " so on Linux (use fullpath)" - }, - "dropper_target_path_linux": { - "title": "Dropper target path on Linux", - "type": "string", - "default": "/tmp/monkey", - "description": "Determines where should the dropper place the monkey on a Linux machine" - }, - "dropper_target_path_win_32": { - "title": "Dropper target path on Windows (32bit)", - "type": "string", - "default": "C:\\Windows\\temp\\monkey32.exe", - "description": "Determines where should the dropper place the monkey on a Windows machine " - "(32bit)" - }, - "dropper_target_path_win_64": { - "title": "Dropper target path on Windows (64bit)", - "type": "string", - "default": "C:\\Windows\\temp\\monkey64.exe", - "description": "Determines where should the dropper place the monkey on a Windows machine " - "(64 bit)" - }, - "dropper_try_move_first": { - "title": "Try to move first", - "type": "boolean", - "default": True, - "description": - "Determines whether the dropper should try to move itself instead of copying itself" - " to target path" - } - } - }, - "logging": { - "title": "Logging", - "type": "object", - "properties": { - "dropper_log_path_linux": { - "title": "Dropper log file path on Linux", - "type": "string", - "default": "/tmp/user-1562", - "description": "The fullpath of the dropper log file on Linux" - }, - "dropper_log_path_windows": { - "title": "Dropper log file path on Windows", - "type": "string", - "default": "%temp%\\~df1562.tmp", - "description": "The fullpath of the dropper log file on Windows" - }, - "monkey_log_path_linux": { - "title": "Monkey log file path on Linux", - "type": "string", - "default": "/tmp/user-1563", - "description": "The fullpath of the monkey log file on Linux" - }, - "monkey_log_path_windows": { - "title": "Monkey log file path on Windows", - "type": "string", - "default": "%temp%\\~df1563.tmp", - "description": "The fullpath of the monkey log file on Windows" - }, - "send_log_to_server": { - "title": "Send log to server", - "type": "boolean", - "default": True, - "description": "Determines whether the monkey sends its log to the Monkey Island server" - } - } - }, - "exploits": { - "title": "Exploits", - "type": "object", - "properties": { - "exploit_lm_hash_list": { - "title": "Exploit LM hash list", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [], - "description": "List of LM hashes to use on exploits using credentials" - }, - "exploit_ntlm_hash_list": { - "title": "Exploit NTLM hash list", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [], - "description": "List of NTLM hashes to use on exploits using credentials" - }, - "exploit_ssh_keys": { - "title": "SSH key pairs list", - "type": "array", - "uniqueItems": True, - "default": [], - "items": { - "type": "string" - }, - "description": "List of SSH key pairs to use, when trying to ssh into servers" - } - } - }, - "testing": { - "title": "Testing", - "type": "object", - "properties": { - "export_monkey_telems": { - "title": "Export monkey telemetries", - "type": "boolean", - "default": False, - "description": "Exports unencrypted telemetries that can be used for tests in development." - " Do not turn on!" - } - } - } - } - }, - "cnc": { - "title": "Monkey Island", - "type": "object", - "properties": { - "servers": { - "title": "Servers", - "type": "object", - "properties": { - "command_servers": { - "title": "Command servers", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "192.0.2.0:5000" - ], - "description": "List of command servers to try and communicate with (format is :)" - }, - "internet_services": { - "title": "Internet services", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "monkey.guardicore.com", - "www.google.com" - ], - "description": - "List of internet services to try and communicate with to determine internet" - " connectivity (use either ip or domain)" - }, - "current_server": { - "title": "Current server", - "type": "string", - "default": "192.0.2.0:5000", - "description": "The current command server the monkey is communicating with" - } - } - }, - } - }, - "exploits": { - "title": "Exploits", - "type": "object", - "properties": { - "general": { - "title": "General", - "type": "object", - "properties": { - "skip_exploit_if_file_exist": { - "title": "Skip exploit if file exists", - "type": "boolean", - "default": False, - "description": "Determines whether the monkey should skip the exploit if the monkey's file" - " is already on the remote machine" - } - } - }, - "ms08_067": { - "title": "MS08_067", - "type": "object", - "properties": { - "ms08_067_exploit_attempts": { - "title": "MS08_067 exploit attempts", - "type": "integer", - "default": 5, - "description": "Number of attempts to exploit using MS08_067" - }, - "user_to_add": { - "title": "Remote user", - "type": "string", - "default": "Monkey_IUSER_SUPPORT", - "description": "Username to add on successful exploit" - }, - "remote_user_pass": { - "title": "Remote user password", - "type": "string", - "default": "Password1!", - "description": "Password to use for created user" - } - } - }, - "sambacry": { - "title": "SambaCry", - "type": "object", - "properties": { - "sambacry_trigger_timeout": { - "title": "SambaCry trigger timeout", - "type": "integer", - "default": 5, - "description": "Timeout (in seconds) of SambaCry trigger" - }, - "sambacry_folder_paths_to_guess": { - "title": "SambaCry folder paths to guess", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - '/', - '/mnt', - '/tmp', - '/storage', - '/export', - '/share', - '/shares', - '/home' - ], - "description": "List of full paths to share folder for SambaCry to guess" - }, - "sambacry_shares_not_to_check": { - "title": "SambaCry shares not to check", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "IPC$", "print$" - ], - "description": "These shares won't be checked when exploiting with SambaCry" - } - } - }, - "smb_service": { - "title": "SMB service", - "type": "object", - "properties": { - "smb_download_timeout": { - "title": "SMB download timeout", - "type": "integer", - "default": 300, - "description": - "Timeout (in seconds) for SMB download operation (used in various exploits using SMB)" - }, - "smb_service_name": { - "title": "SMB service name", - "type": "string", - "default": "InfectionMonkey", - "description": "Name of the SMB service that will be set up to download monkey" - } - } - } - } - }, - "network": { - "title": "Network", - "type": "object", - "properties": { - "tcp_scanner": { - "title": "TCP scanner", - "type": "object", - "properties": { - "HTTP_PORTS": { - "title": "HTTP ports", - "type": "array", - "uniqueItems": True, - "items": { - "type": "integer" - }, - "default": [ - 80, - 8080, - 443, - 8008, - 7001 - ], - "description": "List of ports the monkey will check if are being used for HTTP" - }, - "tcp_target_ports": { - "title": "TCP target ports", - "type": "array", - "uniqueItems": True, - "items": { - "type": "integer" - }, - "default": [ - 22, - 2222, - 445, - 135, - 3389, - 80, - 8080, - 443, - 8008, - 3306, - 9200, - 7001, - 8088 - ], - "description": "List of TCP ports the monkey will check whether they're open" - }, - "tcp_scan_interval": { - "title": "TCP scan interval", - "type": "integer", - "default": 0, - "description": "Time to sleep (in milliseconds) between scans" - }, - "tcp_scan_timeout": { - "title": "TCP scan timeout", - "type": "integer", - "default": 3000, - "description": "Maximum time (in milliseconds) to wait for TCP response" - }, - "tcp_scan_get_banner": { - "title": "TCP scan - get banner", - "type": "boolean", - "default": True, - "description": "Determines whether the TCP scan should try to get the banner" - } - } - }, - "ping_scanner": { - "title": "Ping scanner", - "type": "object", - "properties": { - "ping_scan_timeout": { - "title": "Ping scan timeout", - "type": "integer", - "default": 1000, - "description": "Maximum time (in milliseconds) to wait for ping response" - } - } - } - } - } - }, - "options": { - "collapsed": True - } -} diff --git a/monkey/monkey_island/cc/services/config_schema/__init__.py b/monkey/monkey_island/cc/services/config_schema/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/services/config_schema/basic.py b/monkey/monkey_island/cc/services/config_schema/basic.py new file mode 100644 index 000000000..6a255fc95 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/basic.py @@ -0,0 +1,69 @@ +BASIC = { + "title": "Exploits", + "type": "object", + "primary": True, + "properties": { + "exploiters": { + "title": "Exploiters", + "type": "object", + "properties": { + "exploiter_classes": { + "title": "Exploiters", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/exploiter_classes" + }, + "default": [ + "SmbExploiter", + "WmiExploiter", + "SSHExploiter", + "ShellShockExploiter", + "SambaCryExploiter", + "ElasticGroovyExploiter", + "Struts2Exploiter", + "WebLogicExploiter", + "HadoopExploiter", + "VSFTPDExploiter", + "MSSQLExploiter" + ] + } + } + }, + "credentials": { + "title": "Credentials", + "type": "object", + "properties": { + "exploit_user_list": { + "title": "Exploit user list", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "Administrator", + "root", + "user" + ], + "description": "List of usernames to use on exploits using credentials" + }, + "exploit_password_list": { + "title": "Exploit password list", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "Password1!", + "1234", + "password", + "12345678" + ], + "description": "List of password to use on exploits using credentials" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py new file mode 100644 index 000000000..3674c0f71 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py @@ -0,0 +1,79 @@ +from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN + +BASIC_NETWORK = { + "title": "Network", + "type": "object", + "properties": { + "scope": { + "title": "Scope", + "type": "object", + "properties": { + "blocked_ips": { + "title": "Blocked IPs", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + ], + "description": "List of IPs to not scan" + }, + "local_network_scan": { + "title": "Local network scan", + "type": "boolean", + "default": True, + "description": "Determines whether the monkey should scan its subnets additionally" + }, + "depth": { + "title": "Distance from island", + "type": "integer", + "default": 2, + "description": + "Amount of hops allowed for the monkey to spread from the island. " + + WARNING_SIGN + + " Note that setting this value too high may result in the monkey propagating too far" + }, + "subnet_scan_list": { + "title": "Scan IP/subnet list", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + ], + "description": + "List of IPs/subnets/hosts the monkey should scan." + " Examples: \"192.168.0.1\", \"192.168.0.5-192.168.0.20\", \"192.168.0.5/24\"," + " \"printer.example\"" + } + } + }, + "network_analysis": { + "title": "Network Analysis", + "type": "object", + "properties": { + "inaccessible_subnets": { + "title": "Network segmentation testing", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + ], + "description": + "Test for network segmentation by providing a list of" + " subnets that should NOT be accessible to each other." + " For example, given the following configuration:" + " '10.0.0.0/24, 11.0.0.2/32, 12.2.3.0/24'" + " a Monkey running on 10.0.0.5 will try to access machines in the following" + " subnets: 11.0.0.2/32, 12.2.3.0/24." + " An alert on successful connections will be shown in the report" + " Additional subnet formats include: 13.0.0.1, 13.0.0.1-13.0.0.5" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/cnc.py b/monkey/monkey_island/cc/services/config_schema/cnc.py new file mode 100644 index 000000000..bade095e8 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/cnc.py @@ -0,0 +1,45 @@ +CNC = { + "title": "Monkey Island", + "type": "object", + "properties": { + "servers": { + "title": "Servers", + "type": "object", + "properties": { + "command_servers": { + "title": "Command servers", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "192.0.2.0:5000" + ], + "description": "List of command servers to try and communicate with (format is :)" + }, + "internet_services": { + "title": "Internet services", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "monkey.guardicore.com", + "www.google.com" + ], + "description": + "List of internet services to try and communicate with to determine internet" + " connectivity (use either ip or domain)" + }, + "current_server": { + "title": "Current server", + "type": "string", + "default": "192.0.2.0:5000", + "description": "The current command server the monkey is communicating with" + } + } + }, + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py new file mode 100644 index 000000000..49dc61ad2 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -0,0 +1,36 @@ +from monkey_island.cc.services.config_schema.basic import BASIC +from monkey_island.cc.services.config_schema.basic_network import BASIC_NETWORK +from monkey_island.cc.services.config_schema.cnc import CNC +from monkey_island.cc.services.config_schema.definitions.exploiter_classes import EXPLOITER_CLASSES +from monkey_island.cc.services.config_schema.definitions.finger_classes import FINGER_CLASSES +from monkey_island.cc.services.config_schema.definitions.post_breach_actions import POST_BREACH_ACTIONS +from monkey_island.cc.services.config_schema.definitions.system_info_collector_classes import \ + SYSTEM_INFO_COLLECTOR_CLASSES +from monkey_island.cc.services.config_schema.exploits import EXPLOITS +from monkey_island.cc.services.config_schema.internal import INTERNAL +from monkey_island.cc.services.config_schema.monkey import MONKEY +from monkey_island.cc.services.config_schema.network import NETWORK + +SCHEMA = { + "title": "Monkey", + "type": "object", + "definitions": { + "exploiter_classes": EXPLOITER_CLASSES, + "system_info_collector_classes": SYSTEM_INFO_COLLECTOR_CLASSES, + "post_breach_actions": POST_BREACH_ACTIONS, + "finger_classes": FINGER_CLASSES + + }, + "properties": { + "basic": BASIC, + "basic_network": BASIC_NETWORK, + "monkey": MONKEY, + "internal": INTERNAL, + "cnc": CNC, + "exploits": EXPLOITS, + "network": NETWORK + }, + "options": { + "collapsed": True + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py new file mode 100644 index 000000000..0b9e97fa1 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py @@ -0,0 +1,130 @@ +from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN + +EXPLOITER_CLASSES = { + "title": "Exploit class", + "description": "Click on exploiter to get more information about it." + WARNING_SIGN + + " Note that using unsafe exploits may cause crashes of the exploited machine/service.", + "type": "string", + "anyOf": [ + { + "type": "string", + "enum": [ + "SmbExploiter" + ], + "title": "SMB Exploiter", + "attack_techniques": ["T1110", "T1075", "T1035"], + "info": "Brute forces using credentials provided by user and" + " hashes gathered by mimikatz.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "WmiExploiter" + ], + "title": "WMI Exploiter", + "attack_techniques": ["T1110", "T1106"], + "info": "Brute forces WMI (Windows Management Instrumentation) " + "using credentials provided by user and hashes gathered by mimikatz.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "MSSQLExploiter" + ], + "title": "MSSQL Exploiter", + "attack_techniques": ["T1110"], + "info": "Tries to brute force into MsSQL server and uses insecure " + "configuration to execute commands on server.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "Ms08_067_Exploiter" + ], + "title": "MS08-067 Exploiter (UNSAFE)", + "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. " + "Uses MS08-067 vulnerability.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "SSHExploiter" + ], + "title": "SSH Exploiter", + "attack_techniques": ["T1110", "T1145", "T1106"], + "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "ShellShockExploiter" + ], + "title": "ShellShock Exploiter", + "info": "CVE-2014-6271, based on logic from " + "https://github.com/nccgroup/shocker/blob/master/shocker.py .", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "SambaCryExploiter" + ], + "title": "SambaCry Exploiter", + "info": "Bruteforces and searches for anonymous shares. Uses Impacket.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "ElasticGroovyExploiter" + ], + "title": "ElasticGroovy Exploiter", + "info": "CVE-2015-1427. Logic is based on Metasploit module.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "Struts2Exploiter" + ], + "title": "Struts2 Exploiter", + "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on " + "https://www.exploit-db.com/exploits/41570 .", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "WebLogicExploiter" + ], + "title": "WebLogic Exploiter", + "info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "HadoopExploiter" + ], + "title": "Hadoop/Yarn Exploiter", + "info": "Remote code execution on HADOOP server with YARN and default settings. " + "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + }, + { + "type": "string", + "enum": [ + "VSFTPDExploiter" + ], + "title": "VSFTPD Exploiter", + "info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. " + "Logic based on Metasploit module.", + "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + } + ] +} diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py new file mode 100644 index 000000000..6fe5e8fea --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/definitions/finger_classes.py @@ -0,0 +1,70 @@ +FINGER_CLASSES = { + "title": "Fingerprint class", + "description": "Fingerprint modules collect info about external services " + "Infection Monkey scans.", + "type": "string", + "anyOf": [ + { + "type": "string", + "enum": [ + "SMBFinger" + ], + "title": "SMBFinger", + "info": "Figures out if SMB is running and what's the version of it.", + "attack_techniques": ["T1210"] + }, + { + "type": "string", + "enum": [ + "SSHFinger" + ], + "title": "SSHFinger", + "info": "Figures out if SSH is running.", + "attack_techniques": ["T1210"] + }, + { + "type": "string", + "enum": [ + "PingScanner" + ], + "title": "PingScanner", + "info": "Tries to identify if host is alive and which OS it's running by ping scan." + }, + { + "type": "string", + "enum": [ + "HTTPFinger" + ], + "title": "HTTPFinger", + "info": "Checks if host has HTTP/HTTPS ports open." + }, + { + "type": "string", + "enum": [ + "MySQLFinger" + ], + "title": "MySQLFinger", + "info": "Checks if MySQL server is running and tries to get it's version.", + "attack_techniques": ["T1210"] + }, + { + "type": "string", + "enum": [ + "MSSQLFinger" + ], + "title": "MSSQLFinger", + "info": "Checks if Microsoft SQL service is running and tries to gather information about it.", + "attack_techniques": ["T1210"] + }, + + { + "type": "string", + "enum": [ + "ElasticFinger" + ], + "title": "ElasticFinger", + "info": "Checks if ElasticSearch is running and attempts to find it's version.", + "attack_techniques": ["T1210"] + } + ] +} diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py new file mode 100644 index 000000000..9e55ee5ba --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py @@ -0,0 +1,70 @@ +POST_BREACH_ACTIONS = { + "title": "Post breach actions", + "description": "Runs scripts/commands on infected machines. These actions safely simulate what an adversary" + "might do after breaching a new machine. Used in ATT&CK and Zero trust reports.", + "type": "string", + "anyOf": [ + { + "type": "string", + "enum": [ + "BackdoorUser" + ], + "title": "Back door user", + "info": "Attempts to create a new user on the system and delete it afterwards.", + "attack_techniques": ["T1136"] + }, + { + "type": "string", + "enum": [ + "CommunicateAsNewUser" + ], + "title": "Communicate as new user", + "info": "Attempts to create a new user, create HTTPS requests as that user and delete the user " + "afterwards.", + "attack_techniques": ["T1136"] + }, + { + "type": "string", + "enum": [ + "ModifyShellStartupFiles" + ], + "title": "Modify shell startup files", + "info": "Attempts to modify shell startup files, like ~/.profile, ~/.bashrc, ~/.bash_profile " + "in linux, and profile.ps1 in windows. Reverts modifications done afterwards.", + "attack_techniques": ["T1156", "T1504"] + }, + { + "type": "string", + "enum": [ + "HiddenFiles" + ], + "title": "Hidden files and directories", + "info": "Attempts to create a hidden file and remove it afterward.", + "attack_techniques": ["T1158"] + }, + { + "type": "string", + "enum": [ + "TrapCommand" + ], + "title": "Trap", + "attack_techniques": ["T1154"] + }, + { + "type": "string", + "enum": [ + "ChangeSetuidSetgid" + ], + "title": "Setuid and Setgid", + "attack_techniques": ["T1166"] + }, + { + "type": "string", + "enum": [ + "ScheduleJobs" + ], + "title": "Job scheduling", + "attack_techniques": ["T1168", "T1053"] + } + ] +} diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py new file mode 100644 index 000000000..c77b77b7c --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py @@ -0,0 +1,48 @@ +from common.data.system_info_collectors_names import (AWS_COLLECTOR, + ENVIRONMENT_COLLECTOR, + HOSTNAME_COLLECTOR, + PROCESS_LIST_COLLECTOR) + +SYSTEM_INFO_COLLECTOR_CLASSES = { + "title": "System Information Collectors", + "description": "Click on a system info collector to find out what it collects.", + "type": "string", + "anyOf": [ + { + "type": "string", + "enum": [ + ENVIRONMENT_COLLECTOR + ], + "title": "Environment collector", + "info": "Collects information about machine's environment (on premise/GCP/AWS).", + "attack_techniques": [] + }, + { + "type": "string", + "enum": [ + AWS_COLLECTOR + ], + "title": "AWS collector", + "info": "If on AWS, collects more information about the AWS instance currently running on.", + "attack_techniques": [] + }, + { + "type": "string", + "enum": [ + HOSTNAME_COLLECTOR + ], + "title": "Hostname collector", + "info": "Collects machine's hostname.", + "attack_techniques": [] + }, + { + "type": "string", + "enum": [ + PROCESS_LIST_COLLECTOR + ], + "title": "Process list collector", + "info": "Collects a list of running processes on the machine.", + "attack_techniques": [] + }, + ] +} diff --git a/monkey/monkey_island/cc/services/config_schema/exploits.py b/monkey/monkey_island/cc/services/config_schema/exploits.py new file mode 100644 index 000000000..acbb2f973 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/exploits.py @@ -0,0 +1,105 @@ +EXPLOITS = { + "title": "Exploits", + "type": "object", + "properties": { + "general": { + "title": "General", + "type": "object", + "properties": { + "skip_exploit_if_file_exist": { + "title": "Skip exploit if file exists", + "type": "boolean", + "default": False, + "description": "Determines whether the monkey should skip the exploit if the monkey's file" + " is already on the remote machine" + } + } + }, + "ms08_067": { + "title": "MS08_067", + "type": "object", + "properties": { + "ms08_067_exploit_attempts": { + "title": "MS08_067 exploit attempts", + "type": "integer", + "default": 5, + "description": "Number of attempts to exploit using MS08_067" + }, + "user_to_add": { + "title": "Remote user", + "type": "string", + "default": "Monkey_IUSER_SUPPORT", + "description": "Username to add on successful exploit" + }, + "remote_user_pass": { + "title": "Remote user password", + "type": "string", + "default": "Password1!", + "description": "Password to use for created user" + } + } + }, + "sambacry": { + "title": "SambaCry", + "type": "object", + "properties": { + "sambacry_trigger_timeout": { + "title": "SambaCry trigger timeout", + "type": "integer", + "default": 5, + "description": "Timeout (in seconds) of SambaCry trigger" + }, + "sambacry_folder_paths_to_guess": { + "title": "SambaCry folder paths to guess", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + '/', + '/mnt', + '/tmp', + '/storage', + '/export', + '/share', + '/shares', + '/home' + ], + "description": "List of full paths to share folder for SambaCry to guess" + }, + "sambacry_shares_not_to_check": { + "title": "SambaCry shares not to check", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "IPC$", "print$" + ], + "description": "These shares won't be checked when exploiting with SambaCry" + } + } + }, + "smb_service": { + "title": "SMB service", + "type": "object", + "properties": { + "smb_download_timeout": { + "title": "SMB download timeout", + "type": "integer", + "default": 300, + "description": + "Timeout (in seconds) for SMB download operation (used in various exploits using SMB)" + }, + "smb_service_name": { + "title": "SMB service name", + "type": "string", + "default": "InfectionMonkey", + "description": "Name of the SMB service that will be set up to download monkey" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py new file mode 100644 index 000000000..755347538 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -0,0 +1,222 @@ +INTERNAL = { + "title": "Internal", + "type": "object", + "properties": { + "general": { + "title": "General", + "type": "object", + "properties": { + "singleton_mutex_name": { + "title": "Singleton mutex name", + "type": "string", + "default": "{2384ec59-0df8-4ab9-918c-843740924a28}", + "description": + "The name of the mutex used to determine whether the monkey is already running" + }, + "keep_tunnel_open_time": { + "title": "Keep tunnel open time", + "type": "integer", + "default": 60, + "description": "Time to keep tunnel open before going down after last exploit (in seconds)" + }, + "monkey_dir_name": { + "title": "Monkey's directory name", + "type": "string", + "default": r"monkey_dir", + "description": "Directory name for the directory which will contain all of the monkey files" + }, + "started_on_island": { + "title": "Started on island", + "type": "boolean", + "default": False, + "description": "Was exploitation started from island" + "(did monkey with max depth ran on island)" + }, + } + }, + "classes": { + "title": "Classes", + "type": "object", + "properties": { + "finger_classes": { + "title": "Fingerprint classes", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/finger_classes" + }, + "default": [ + "SMBFinger", + "SSHFinger", + "PingScanner", + "HTTPFinger", + "MySQLFinger", + "MSSQLFinger", + "ElasticFinger" + ] + } + } + }, + "kill_file": { + "title": "Kill file", + "type": "object", + "properties": { + "kill_file_path_windows": { + "title": "Kill file path on Windows", + "type": "string", + "default": "%windir%\\monkey.not", + "description": "Path of file which kills monkey if it exists (on Windows)" + }, + "kill_file_path_linux": { + "title": "Kill file path on Linux", + "type": "string", + "default": "/var/run/monkey.not", + "description": "Path of file which kills monkey if it exists (on Linux)" + } + } + }, + "dropper": { + "title": "Dropper", + "type": "object", + "properties": { + "dropper_set_date": { + "title": "Dropper sets date", + "type": "boolean", + "default": True, + "description": + "Determines whether the dropper should set the monkey's file date to be the same as" + " another file" + }, + "dropper_date_reference_path_windows": { + "title": "Dropper date reference path (Windows)", + "type": "string", + "default": "%windir%\\system32\\kernel32.dll", + "description": + "Determines which file the dropper should copy the date from if it's configured to do" + " so on Windows (use fullpath)" + }, + "dropper_date_reference_path_linux": { + "title": "Dropper date reference path (Linux)", + "type": "string", + "default": "/bin/sh", + "description": + "Determines which file the dropper should copy the date from if it's configured to do" + " so on Linux (use fullpath)" + }, + "dropper_target_path_linux": { + "title": "Dropper target path on Linux", + "type": "string", + "default": "/tmp/monkey", + "description": "Determines where should the dropper place the monkey on a Linux machine" + }, + "dropper_target_path_win_32": { + "title": "Dropper target path on Windows (32bit)", + "type": "string", + "default": "C:\\Windows\\temp\\monkey32.exe", + "description": "Determines where should the dropper place the monkey on a Windows machine " + "(32bit)" + }, + "dropper_target_path_win_64": { + "title": "Dropper target path on Windows (64bit)", + "type": "string", + "default": "C:\\Windows\\temp\\monkey64.exe", + "description": "Determines where should the dropper place the monkey on a Windows machine " + "(64 bit)" + }, + "dropper_try_move_first": { + "title": "Try to move first", + "type": "boolean", + "default": True, + "description": + "Determines whether the dropper should try to move itself instead of copying itself" + " to target path" + } + } + }, + "logging": { + "title": "Logging", + "type": "object", + "properties": { + "dropper_log_path_linux": { + "title": "Dropper log file path on Linux", + "type": "string", + "default": "/tmp/user-1562", + "description": "The fullpath of the dropper log file on Linux" + }, + "dropper_log_path_windows": { + "title": "Dropper log file path on Windows", + "type": "string", + "default": "%temp%\\~df1562.tmp", + "description": "The fullpath of the dropper log file on Windows" + }, + "monkey_log_path_linux": { + "title": "Monkey log file path on Linux", + "type": "string", + "default": "/tmp/user-1563", + "description": "The fullpath of the monkey log file on Linux" + }, + "monkey_log_path_windows": { + "title": "Monkey log file path on Windows", + "type": "string", + "default": "%temp%\\~df1563.tmp", + "description": "The fullpath of the monkey log file on Windows" + }, + "send_log_to_server": { + "title": "Send log to server", + "type": "boolean", + "default": True, + "description": "Determines whether the monkey sends its log to the Monkey Island server" + } + } + }, + "exploits": { + "title": "Exploits", + "type": "object", + "properties": { + "exploit_lm_hash_list": { + "title": "Exploit LM hash list", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [], + "description": "List of LM hashes to use on exploits using credentials" + }, + "exploit_ntlm_hash_list": { + "title": "Exploit NTLM hash list", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [], + "description": "List of NTLM hashes to use on exploits using credentials" + }, + "exploit_ssh_keys": { + "title": "SSH key pairs list", + "type": "array", + "uniqueItems": True, + "default": [], + "items": { + "type": "string" + }, + "description": "List of SSH key pairs to use, when trying to ssh into servers" + } + } + }, + "testing": { + "title": "Testing", + "type": "object", + "properties": { + "export_monkey_telems": { + "title": "Export monkey telemetries", + "type": "boolean", + "default": False, + "description": "Exports unencrypted telemetries that can be used for tests in development." + " Do not turn on!" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py new file mode 100644 index 000000000..924a077d0 --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -0,0 +1,190 @@ +from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN +from common.data.system_info_collectors_names import (AWS_COLLECTOR, + ENVIRONMENT_COLLECTOR, + HOSTNAME_COLLECTOR, + PROCESS_LIST_COLLECTOR) + +MONKEY = { + "title": "Monkey", + "type": "object", + "properties": { + "general": { + "title": "General", + "type": "object", + "properties": { + "alive": { + "title": "Alive", + "type": "boolean", + "default": True, + "description": "Is the monkey alive" + }, + "post_breach_actions": { + "title": "Post breach actions", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/post_breach_actions" + }, + "default": [ + "BackdoorUser", + "CommunicateAsNewUser", + "ModifyShellStartupFiles", + "HiddenFiles", + "TrapCommand", + "ChangeSetuidSetgid", + "ScheduleJobs" + ] + }, + } + }, + "behaviour": { + "title": "Behaviour", + "type": "object", + "properties": { + "custom_PBA_linux_cmd": { + "title": "Linux post breach command", + "type": "string", + "default": "", + "description": "Linux command to be executed after breaching." + }, + "PBA_linux_file": { + "title": "Linux post breach file", + "type": "string", + "format": "data-url", + "description": "File to be executed after breaching. " + "If you want custom execution behavior, " + "specify it in 'Linux post breach command' field. " + "Reference your file by filename." + }, + "custom_PBA_windows_cmd": { + "title": "Windows post breach command", + "type": "string", + "default": "", + "description": "Windows command to be executed after breaching." + }, + "PBA_windows_file": { + "title": "Windows post breach file", + "type": "string", + "format": "data-url", + "description": "File to be executed after breaching. " + "If you want custom execution behavior, " + "specify it in 'Windows post breach command' field. " + "Reference your file by filename." + }, + "PBA_windows_filename": { + "title": "Windows PBA filename", + "type": "string", + "default": "" + }, + "PBA_linux_filename": { + "title": "Linux PBA filename", + "type": "string", + "default": "" + }, + "self_delete_in_cleanup": { + "title": "Self delete on cleanup", + "type": "boolean", + "default": True, + "description": "Should the monkey delete its executable when going down" + }, + "use_file_logging": { + "title": "Use file logging", + "type": "boolean", + "default": True, + "description": "Should the monkey dump to a log file" + }, + "serialize_config": { + "title": "Serialize config", + "type": "boolean", + "default": False, + "description": "Should the monkey dump its config on startup" + } + } + }, + "system_info": { + "title": "System info", + "type": "object", + "properties": { + "extract_azure_creds": { + "title": "Harvest Azure Credentials", + "type": "boolean", + "default": True, + "attack_techniques": ["T1003"], + "description": + "Determine if the Monkey should try to harvest password credentials from Azure VMs" + }, + "collect_system_info": { + "title": "Collect system info", + "type": "boolean", + "default": True, + "attack_techniques": ["T1082", "T1005", "T1016"], + "description": "Determines whether to collect system info" + }, + "should_use_mimikatz": { + "title": "Should use Mimikatz", + "type": "boolean", + "default": True, + "attack_techniques": ["T1003"], + "description": "Determines whether to use Mimikatz" + }, + "system_info_collector_classes": { + "title": "System info collectors", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/system_info_collector_classes" + }, + "default": [ + ENVIRONMENT_COLLECTOR, + AWS_COLLECTOR, + HOSTNAME_COLLECTOR, + PROCESS_LIST_COLLECTOR + ] + }, + } + }, + "life_cycle": { + "title": "Life cycle", + "type": "object", + "properties": { + "max_iterations": { + "title": "Max iterations", + "type": "integer", + "default": 1, + "description": "Determines how many iterations of the monkey's full lifecycle should occur" + }, + "victims_max_find": { + "title": "Max victims to find", + "type": "integer", + "default": 100, + "description": "Determines the maximum number of machines the monkey is allowed to scan" + }, + "victims_max_exploit": { + "title": "Max victims to exploit", + "type": "integer", + "default": 15, + "description": + "Determines the maximum number of machines the monkey" + " is allowed to successfully exploit. " + WARNING_SIGN + + " Note that setting this value too high may result in the monkey propagating to " + "a high number of machines" + }, + "timeout_between_iterations": { + "title": "Wait time between iterations", + "type": "integer", + "default": 100, + "description": + "Determines for how long (in seconds) should the monkey wait between iterations" + }, + "retry_failed_explotation": { + "title": "Retry failed exploitation", + "type": "boolean", + "default": True, + "description": + "Determines whether the monkey should retry exploiting machines" + " it didn't successfully exploit on previous iterations" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/config_schema/network.py b/monkey/monkey_island/cc/services/config_schema/network.py new file mode 100644 index 000000000..3ded2658f --- /dev/null +++ b/monkey/monkey_island/cc/services/config_schema/network.py @@ -0,0 +1,82 @@ +NETWORK = { + "title": "Network", + "type": "object", + "properties": { + "tcp_scanner": { + "title": "TCP scanner", + "type": "object", + "properties": { + "HTTP_PORTS": { + "title": "HTTP ports", + "type": "array", + "uniqueItems": True, + "items": { + "type": "integer" + }, + "default": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "description": "List of ports the monkey will check if are being used for HTTP" + }, + "tcp_target_ports": { + "title": "TCP target ports", + "type": "array", + "uniqueItems": True, + "items": { + "type": "integer" + }, + "default": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001, + 8088 + ], + "description": "List of TCP ports the monkey will check whether they're open" + }, + "tcp_scan_interval": { + "title": "TCP scan interval", + "type": "integer", + "default": 0, + "description": "Time to sleep (in milliseconds) between scans" + }, + "tcp_scan_timeout": { + "title": "TCP scan timeout", + "type": "integer", + "default": 3000, + "description": "Maximum time (in milliseconds) to wait for TCP response" + }, + "tcp_scan_get_banner": { + "title": "TCP scan - get banner", + "type": "boolean", + "default": True, + "description": "Determines whether the TCP scan should try to get the banner" + } + } + }, + "ping_scanner": { + "title": "Ping scanner", + "type": "object", + "properties": { + "ping_scan_timeout": { + "title": "Ping scan timeout", + "type": "integer", + "default": 1000, + "description": "Maximum time (in milliseconds) to wait for ping response" + } + } + } + } +} diff --git a/monkey/monkey_island/cc/services/utils/__init__.py b/monkey/monkey_island/cc/services/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/services/utils/typographic_symbols.py b/monkey/monkey_island/cc/services/utils/typographic_symbols.py new file mode 100644 index 000000000..ab87f169e --- /dev/null +++ b/monkey/monkey_island/cc/services/utils/typographic_symbols.py @@ -0,0 +1 @@ +WARNING_SIGN = " \u26A0" diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 3b1e233d8..6185ca647 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -59,7 +59,7 @@ export default function UiSchema(props) { } }, system_info: { - system_info_collectors_classes: { + system_info_collector_classes: { classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } From 2c96ace9083848c582730cc0d0e4bec926c85d62 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Wed, 22 Jul 2020 18:06:49 +0300 Subject: [PATCH 15/40] Mimikatz, Azure collectors moved to system info collectors in config, "Behaviour" renamed to "Post breach" in config --- .../data/system_info_collectors_names.py | 2 + monkey/infection_monkey/config.py | 10 --- monkey/infection_monkey/monkey.py | 15 ++-- .../infection_monkey/system_info/__init__.py | 3 +- .../system_info/windows_info_collector.py | 3 +- .../system_info_collector_classes.py | 30 +++++-- .../cc/services/config_schema/internal.py | 24 ++++++ .../cc/services/config_schema/monkey.py | 82 +++++-------------- .../cc/services/post_breach_files.py | 8 +- .../configuration-components/UiSchema.js | 2 +- .../ui/src/components/pages/ConfigurePage.js | 8 +- 11 files changed, 94 insertions(+), 93 deletions(-) diff --git a/monkey/common/data/system_info_collectors_names.py b/monkey/common/data/system_info_collectors_names.py index 831bbe142..175a054e1 100644 --- a/monkey/common/data/system_info_collectors_names.py +++ b/monkey/common/data/system_info_collectors_names.py @@ -2,3 +2,5 @@ AWS_COLLECTOR = "AwsCollector" HOSTNAME_COLLECTOR = "HostnameCollector" ENVIRONMENT_COLLECTOR = "EnvironmentCollector" PROCESS_LIST_COLLECTOR = "ProcessListCollector" +MIMIKATZ_COLLECTOR = "MimikatzCollector" +AZURE_CRED_COLLECTOR = "AzureCollector" diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 0413bdcd3..b87ef9ed8 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -267,16 +267,6 @@ class Configuration(object): # Shares to not check if they're writable. sambacry_shares_not_to_check = ["IPC$", "print$"] - # system info collection - collect_system_info = True - should_use_mimikatz = True - - ########################### - # systeminfo config - ########################### - - extract_azure_creds = True - ########################### # post breach actions ########################### diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index e01338a48..444bde452 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -190,7 +190,8 @@ class InfectionMonkey(object): if self._default_server: if self._network.on_island(self._default_server): machine.set_default_server(get_interface_to_target(machine.ip_addr) + - (':' + self._default_server_port if self._default_server_port else '')) + ( + ':' + self._default_server_port if self._default_server_port else '')) else: machine.set_default_server(self._default_server) LOG.debug("Default server for machine: %r set to %s" % (machine, machine.default_server)) @@ -241,11 +242,10 @@ class InfectionMonkey(object): LOG.debug("Running with depth: %d" % WormConfiguration.depth) def collect_system_info_if_configured(self): - if WormConfiguration.collect_system_info: - LOG.debug("Calling system info collection") - system_info_collector = SystemInfoCollector() - system_info = system_info_collector.get_info() - SystemInfoTelem(system_info).send() + LOG.debug("Calling system info collection") + system_info_collector = SystemInfoCollector() + system_info = system_info_collector.get_info() + SystemInfoTelem(system_info).send() def shutdown_by_not_alive_config(self): if not WormConfiguration.alive: @@ -386,7 +386,8 @@ class InfectionMonkey(object): :raises PlannedShutdownException if couldn't find the server. """ if not ControlClient.find_server(default_tunnel=self._default_tunnel): - raise PlannedShutdownException("Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel)) + raise PlannedShutdownException( + "Monkey couldn't find server with {} default tunnel.".format(self._default_tunnel)) self._default_server = WormConfiguration.current_server LOG.debug("default server set to: %s" % self._default_server) diff --git a/monkey/infection_monkey/system_info/__init__.py b/monkey/infection_monkey/system_info/__init__.py index 7761a412b..05bb3a4d0 100644 --- a/monkey/infection_monkey/system_info/__init__.py +++ b/monkey/infection_monkey/system_info/__init__.py @@ -4,6 +4,7 @@ from enum import IntEnum import psutil +from common.data.system_info_collectors_names import AZURE_CRED_COLLECTOR from infection_monkey.network.info import get_host_subnets from infection_monkey.system_info.azure_cred_collector import AzureCollector from infection_monkey.system_info.netstat_collector import NetstatCollector @@ -91,7 +92,7 @@ class InfoCollector(object): # noinspection PyBroadException try: from infection_monkey.config import WormConfiguration - if not WormConfiguration.extract_azure_creds: + if AZURE_CRED_COLLECTOR not in WormConfiguration.system_info_collector_classes: return LOG.debug("Harvesting creds if on an Azure machine") azure_collector = AzureCollector() diff --git a/monkey/infection_monkey/system_info/windows_info_collector.py b/monkey/infection_monkey/system_info/windows_info_collector.py index 7eb80377d..d6b3cbec8 100644 --- a/monkey/infection_monkey/system_info/windows_info_collector.py +++ b/monkey/infection_monkey/system_info/windows_info_collector.py @@ -2,6 +2,7 @@ import logging import os import sys +from common.data.system_info_collectors_names import MIMIKATZ_COLLECTOR from infection_monkey.system_info.windows_cred_collector.mimikatz_cred_collector import \ MimikatzCredentialCollector @@ -44,7 +45,7 @@ class WindowsInfoCollector(InfoCollector): # TODO: Think about returning self.get_wmi_info() self.get_installed_packages() from infection_monkey.config import WormConfiguration - if WormConfiguration.should_use_mimikatz: + if MIMIKATZ_COLLECTOR in WormConfiguration.system_info_collector_classes: self.get_mimikatz_info() return self.info diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py index c77b77b7c..8b960d1d8 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py @@ -1,7 +1,9 @@ from common.data.system_info_collectors_names import (AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR) + PROCESS_LIST_COLLECTOR, + MIMIKATZ_COLLECTOR, + AZURE_CRED_COLLECTOR) SYSTEM_INFO_COLLECTOR_CLASSES = { "title": "System Information Collectors", @@ -15,7 +17,16 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Environment collector", "info": "Collects information about machine's environment (on premise/GCP/AWS).", - "attack_techniques": [] + "attack_techniques": ["T1082"] + }, + { + "type": "string", + "enum": [ + MIMIKATZ_COLLECTOR + ], + "title": "Mimikatz collector", + "info": "Collects credentials from Windows credential manager.", + "attack_techniques": ["T1003", "T1005"] }, { "type": "string", @@ -24,7 +35,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "AWS collector", "info": "If on AWS, collects more information about the AWS instance currently running on.", - "attack_techniques": [] + "attack_techniques": ["T1082"] }, { "type": "string", @@ -33,7 +44,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Hostname collector", "info": "Collects machine's hostname.", - "attack_techniques": [] + "attack_techniques": ["T1082", "T1016"] }, { "type": "string", @@ -42,7 +53,16 @@ SYSTEM_INFO_COLLECTOR_CLASSES = { ], "title": "Process list collector", "info": "Collects a list of running processes on the machine.", - "attack_techniques": [] + "attack_techniques": ["T1082"] }, + { + "type": "string", + "enum": [ + AZURE_CRED_COLLECTOR + ], + "title": "Azure credential collector", + "info": "Collects password credentials from Azure VMs", + "attack_techniques": ["T1003", "T1005"] + } ] } diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 755347538..b84137024 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -34,6 +34,30 @@ INTERNAL = { }, } }, + "monkey": { + "title": "Monkey", + "type": "object", + "properties": { + "self_delete_in_cleanup": { + "title": "Self delete on cleanup", + "type": "boolean", + "default": True, + "description": "Should the monkey delete its executable when going down" + }, + "use_file_logging": { + "title": "Use file logging", + "type": "boolean", + "default": True, + "description": "Should the monkey dump to a log file" + }, + "serialize_config": { + "title": "Serialize config", + "type": "boolean", + "default": False, + "description": "Should the monkey dump its config on startup" + } + } + }, "classes": { "title": "Classes", "type": "object", diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 924a077d0..92f8d3cc1 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -2,7 +2,7 @@ from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN from common.data.system_info_collectors_names import (AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR) + PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, AZURE_CRED_COLLECTOR) MONKEY = { "title": "Monkey", @@ -18,27 +18,10 @@ MONKEY = { "default": True, "description": "Is the monkey alive" }, - "post_breach_actions": { - "title": "Post breach actions", - "type": "array", - "uniqueItems": True, - "items": { - "$ref": "#/definitions/post_breach_actions" - }, - "default": [ - "BackdoorUser", - "CommunicateAsNewUser", - "ModifyShellStartupFiles", - "HiddenFiles", - "TrapCommand", - "ChangeSetuidSetgid", - "ScheduleJobs" - ] - }, } }, - "behaviour": { - "title": "Behaviour", + "post_breach": { + "title": "Post breach", "type": "object", "properties": { "custom_PBA_linux_cmd": { @@ -81,52 +64,29 @@ MONKEY = { "type": "string", "default": "" }, - "self_delete_in_cleanup": { - "title": "Self delete on cleanup", - "type": "boolean", - "default": True, - "description": "Should the monkey delete its executable when going down" + "post_breach_actions": { + "title": "Post breach actions", + "type": "array", + "uniqueItems": True, + "items": { + "$ref": "#/definitions/post_breach_actions" + }, + "default": [ + "BackdoorUser", + "CommunicateAsNewUser", + "ModifyShellStartupFiles", + "HiddenFiles", + "TrapCommand", + "ChangeSetuidSetgid", + "ScheduleJobs" + ] }, - "use_file_logging": { - "title": "Use file logging", - "type": "boolean", - "default": True, - "description": "Should the monkey dump to a log file" - }, - "serialize_config": { - "title": "Serialize config", - "type": "boolean", - "default": False, - "description": "Should the monkey dump its config on startup" - } } }, "system_info": { "title": "System info", "type": "object", "properties": { - "extract_azure_creds": { - "title": "Harvest Azure Credentials", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": - "Determine if the Monkey should try to harvest password credentials from Azure VMs" - }, - "collect_system_info": { - "title": "Collect system info", - "type": "boolean", - "default": True, - "attack_techniques": ["T1082", "T1005", "T1016"], - "description": "Determines whether to collect system info" - }, - "should_use_mimikatz": { - "title": "Should use Mimikatz", - "type": "boolean", - "default": True, - "attack_techniques": ["T1003"], - "description": "Determines whether to use Mimikatz" - }, "system_info_collector_classes": { "title": "System info collectors", "type": "array", @@ -138,7 +98,9 @@ MONKEY = { ENVIRONMENT_COLLECTOR, AWS_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR + PROCESS_LIST_COLLECTOR, + MIMIKATZ_COLLECTOR, + AZURE_CRED_COLLECTOR ] }, } diff --git a/monkey/monkey_island/cc/services/post_breach_files.py b/monkey/monkey_island/cc/services/post_breach_files.py index fe4f47ddd..e3e6266cb 100644 --- a/monkey/monkey_island/cc/services/post_breach_files.py +++ b/monkey/monkey_island/cc/services/post_breach_files.py @@ -9,8 +9,8 @@ __author__ = "VakarisZ" logger = logging.getLogger(__name__) # Where to find file names in config -PBA_WINDOWS_FILENAME_PATH = ['monkey', 'behaviour', 'PBA_windows_filename'] -PBA_LINUX_FILENAME_PATH = ['monkey', 'behaviour', 'PBA_linux_filename'] +PBA_WINDOWS_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_windows_filename'] +PBA_LINUX_FILENAME_PATH = ['monkey', 'post_breach', 'PBA_linux_filename'] UPLOADS_DIR = Path('monkey_island', 'cc', 'userUploads') @@ -41,5 +41,5 @@ def set_config_PBA_files(config_json): if monkey_island.cc.services.config.ConfigService.get_config(): linux_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_LINUX_FILENAME_PATH) windows_filename = monkey_island.cc.services.config.ConfigService.get_config_value(PBA_WINDOWS_FILENAME_PATH) - config_json['monkey']['behaviour']['PBA_linux_filename'] = linux_filename - config_json['monkey']['behaviour']['PBA_windows_filename'] = windows_filename + config_json['monkey']['post_breach']['PBA_linux_filename'] = linux_filename + config_json['monkey']['post_breach']['PBA_windows_filename'] = windows_filename diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 6185ca647..a6e22cd77 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -24,7 +24,7 @@ export default function UiSchema(props) { 'ui:widget': AdvancedMultiSelect } }, - behaviour: { + post_breach: { custom_PBA_linux_cmd: { 'ui:widget': 'textarea', 'ui:emptyValue': '' diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index e2042fa69..ffef85739 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -334,8 +334,8 @@ class ConfigurePageComponent extends AuthComponent { {this.renderBasicNetworkWarning()} { let config = this.state.configuration - config.monkey.behaviour.PBA_windows_filename = filename + config.monkey.post_breach.PBA_windows_filename = filename this.setState({ configuration: config }) @@ -359,7 +359,7 @@ class ConfigurePageComponent extends AuthComponent { setPbaFilenameLinux = (filename) => { let config = this.state.configuration - config.monkey.behaviour.PBA_linux_filename = filename + config.monkey.post_breach.PBA_linux_filename = filename this.setState({ configuration: config }) From 57ee55d9ff1fb87d8114e5e9cc326bd5da70f590 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 09:12:27 +0300 Subject: [PATCH 16/40] Moved "is monkey alive" into internal(still hidden) config, fixed PBA UI --- .../cc/services/config_schema/internal.py | 50 +++++++++++-------- .../cc/services/config_schema/monkey.py | 12 ----- .../configuration-components/UiSchema.js | 14 +++--- 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index b84137024..36370d0b9 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -35,28 +35,34 @@ INTERNAL = { } }, "monkey": { - "title": "Monkey", - "type": "object", - "properties": { - "self_delete_in_cleanup": { - "title": "Self delete on cleanup", - "type": "boolean", - "default": True, - "description": "Should the monkey delete its executable when going down" - }, - "use_file_logging": { - "title": "Use file logging", - "type": "boolean", - "default": True, - "description": "Should the monkey dump to a log file" - }, - "serialize_config": { - "title": "Serialize config", - "type": "boolean", - "default": False, - "description": "Should the monkey dump its config on startup" - } - } + "title": "Monkey", + "type": "object", + "properties": { + "self_delete_in_cleanup": { + "title": "Self delete on cleanup", + "type": "boolean", + "default": True, + "description": "Should the monkey delete its executable when going down" + }, + "use_file_logging": { + "title": "Use file logging", + "type": "boolean", + "default": True, + "description": "Should the monkey dump to a log file" + }, + "serialize_config": { + "title": "Serialize config", + "type": "boolean", + "default": False, + "description": "Should the monkey dump its config on startup" + }, + "alive": { + "title": "Alive", + "type": "boolean", + "default": True, + "description": "Is the monkey alive" + } + } }, "classes": { "title": "Classes", diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 92f8d3cc1..d699da061 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -8,18 +8,6 @@ MONKEY = { "title": "Monkey", "type": "object", "properties": { - "general": { - "title": "General", - "type": "object", - "properties": { - "alive": { - "title": "Alive", - "type": "boolean", - "default": True, - "description": "Is the monkey alive" - }, - } - }, "post_breach": { "title": "Post breach", "type": "object", diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index a6e22cd77..193414bdb 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -15,16 +15,11 @@ export default function UiSchema(props) { }, basic_network: {}, monkey: { - general: { - alive: { - classNames: 'config-field-hidden' - }, + post_breach: { post_breach_actions: { classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect - } - }, - post_breach: { + }, custom_PBA_linux_cmd: { 'ui:widget': 'textarea', 'ui:emptyValue': '' @@ -76,6 +71,11 @@ export default function UiSchema(props) { classNames: 'config-template-no-header', 'ui:widget': AdvancedMultiSelect } + }, + monkey: { + alive: { + classNames: 'config-field-hidden' + } } } } From b2eb5a40ad560667cfd4e19cb32615c34dc6da2f Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 09:44:13 +0300 Subject: [PATCH 17/40] Removed "Monkey island" config tab (moved everything into internal) --- .../attack/technique_reports/T1065.py | 2 +- monkey/monkey_island/cc/services/config.py | 4 +- .../cc/services/config_schema/cnc.py | 45 ------------------- .../services/config_schema/config_schema.py | 2 - .../cc/services/config_schema/internal.py | 40 +++++++++++++++++ 5 files changed, 43 insertions(+), 50 deletions(-) delete mode 100644 monkey/monkey_island/cc/services/config_schema/cnc.py diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py index 8df625284..cd4d69ae8 100644 --- a/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1065.py @@ -14,6 +14,6 @@ class T1065(AttackTechnique): @staticmethod def get_report_data(): - port = ConfigService.get_config_value(['cnc', 'servers', 'current_server']).split(':')[1] + port = ConfigService.get_config_value(['internal', 'island_server', 'current_server']).split(':')[1] T1065.used_msg = T1065.message % port return T1065.get_base_data_by_status(ScanStatus.USED.value) diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index 5b6c4529b..341297435 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -218,8 +218,8 @@ class ConfigService: @staticmethod def set_server_ips_in_config(config): ips = local_ip_addresses() - config["cnc"]["servers"]["command_servers"] = ["%s:%d" % (ip, env_singleton.env.get_island_port()) for ip in ips] - config["cnc"]["servers"]["current_server"] = "%s:%d" % (ips[0], env_singleton.env.get_island_port()) + 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 def save_initial_config_if_needed(): diff --git a/monkey/monkey_island/cc/services/config_schema/cnc.py b/monkey/monkey_island/cc/services/config_schema/cnc.py deleted file mode 100644 index bade095e8..000000000 --- a/monkey/monkey_island/cc/services/config_schema/cnc.py +++ /dev/null @@ -1,45 +0,0 @@ -CNC = { - "title": "Monkey Island", - "type": "object", - "properties": { - "servers": { - "title": "Servers", - "type": "object", - "properties": { - "command_servers": { - "title": "Command servers", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "192.0.2.0:5000" - ], - "description": "List of command servers to try and communicate with (format is :)" - }, - "internet_services": { - "title": "Internet services", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "monkey.guardicore.com", - "www.google.com" - ], - "description": - "List of internet services to try and communicate with to determine internet" - " connectivity (use either ip or domain)" - }, - "current_server": { - "title": "Current server", - "type": "string", - "default": "192.0.2.0:5000", - "description": "The current command server the monkey is communicating with" - } - } - }, - } -} diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py index 49dc61ad2..91e1a686b 100644 --- a/monkey/monkey_island/cc/services/config_schema/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -1,6 +1,5 @@ from monkey_island.cc.services.config_schema.basic import BASIC from monkey_island.cc.services.config_schema.basic_network import BASIC_NETWORK -from monkey_island.cc.services.config_schema.cnc import CNC from monkey_island.cc.services.config_schema.definitions.exploiter_classes import EXPLOITER_CLASSES from monkey_island.cc.services.config_schema.definitions.finger_classes import FINGER_CLASSES from monkey_island.cc.services.config_schema.definitions.post_breach_actions import POST_BREACH_ACTIONS @@ -26,7 +25,6 @@ SCHEMA = { "basic_network": BASIC_NETWORK, "monkey": MONKEY, "internal": INTERNAL, - "cnc": CNC, "exploits": EXPLOITS, "network": NETWORK }, diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 36370d0b9..cccd7abb3 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -38,6 +38,21 @@ INTERNAL = { "title": "Monkey", "type": "object", "properties": { + "internet_services": { + "title": "Internet services", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "monkey.guardicore.com", + "www.google.com" + ], + "description": + "List of internet services to try and communicate with to determine internet" + " connectivity (use either ip or domain)" + }, "self_delete_in_cleanup": { "title": "Self delete on cleanup", "type": "boolean", @@ -64,6 +79,31 @@ INTERNAL = { } } }, + "island_server": { + "title": "Island server", + "type": "object", + "properties": { + "command_servers": { + "title": "Island server's IP's", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "192.0.2.0:5000" + ], + "description": "List of command servers/network interfaces to try to communicate with " + "(format is :)" + }, + "current_server": { + "title": "Current server", + "type": "string", + "default": "192.0.2.0:5000", + "description": "The current command server the monkey is communicating with" + } + } + }, "classes": { "title": "Classes", "type": "object", From 2506fdc501d605639ede8dffe62f1246e5fa4f21 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 10:18:03 +0300 Subject: [PATCH 18/40] "Network" config section moved to "Internal" --- .../cc/services/config_schema/internal.py | 82 +++++++++++++++++++ .../cc/services/config_schema/network.py | 82 ------------------- 2 files changed, 82 insertions(+), 82 deletions(-) delete mode 100644 monkey/monkey_island/cc/services/config_schema/network.py diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index cccd7abb3..26ed8bc4c 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -104,6 +104,88 @@ INTERNAL = { } } }, + "network": { + "title": "Network", + "type": "object", + "properties": { + "tcp_scanner": { + "title": "TCP scanner", + "type": "object", + "properties": { + "HTTP_PORTS": { + "title": "HTTP ports", + "type": "array", + "uniqueItems": True, + "items": { + "type": "integer" + }, + "default": [ + 80, + 8080, + 443, + 8008, + 7001 + ], + "description": "List of ports the monkey will check if are being used for HTTP" + }, + "tcp_target_ports": { + "title": "TCP target ports", + "type": "array", + "uniqueItems": True, + "items": { + "type": "integer" + }, + "default": [ + 22, + 2222, + 445, + 135, + 3389, + 80, + 8080, + 443, + 8008, + 3306, + 9200, + 7001, + 8088 + ], + "description": "List of TCP ports the monkey will check whether they're open" + }, + "tcp_scan_interval": { + "title": "TCP scan interval", + "type": "integer", + "default": 0, + "description": "Time to sleep (in milliseconds) between scans" + }, + "tcp_scan_timeout": { + "title": "TCP scan timeout", + "type": "integer", + "default": 3000, + "description": "Maximum time (in milliseconds) to wait for TCP response" + }, + "tcp_scan_get_banner": { + "title": "TCP scan - get banner", + "type": "boolean", + "default": True, + "description": "Determines whether the TCP scan should try to get the banner" + } + } + }, + "ping_scanner": { + "title": "Ping scanner", + "type": "object", + "properties": { + "ping_scan_timeout": { + "title": "Ping scan timeout", + "type": "integer", + "default": 1000, + "description": "Maximum time (in milliseconds) to wait for ping response" + } + } + } + } + }, "classes": { "title": "Classes", "type": "object", diff --git a/monkey/monkey_island/cc/services/config_schema/network.py b/monkey/monkey_island/cc/services/config_schema/network.py deleted file mode 100644 index 3ded2658f..000000000 --- a/monkey/monkey_island/cc/services/config_schema/network.py +++ /dev/null @@ -1,82 +0,0 @@ -NETWORK = { - "title": "Network", - "type": "object", - "properties": { - "tcp_scanner": { - "title": "TCP scanner", - "type": "object", - "properties": { - "HTTP_PORTS": { - "title": "HTTP ports", - "type": "array", - "uniqueItems": True, - "items": { - "type": "integer" - }, - "default": [ - 80, - 8080, - 443, - 8008, - 7001 - ], - "description": "List of ports the monkey will check if are being used for HTTP" - }, - "tcp_target_ports": { - "title": "TCP target ports", - "type": "array", - "uniqueItems": True, - "items": { - "type": "integer" - }, - "default": [ - 22, - 2222, - 445, - 135, - 3389, - 80, - 8080, - 443, - 8008, - 3306, - 9200, - 7001, - 8088 - ], - "description": "List of TCP ports the monkey will check whether they're open" - }, - "tcp_scan_interval": { - "title": "TCP scan interval", - "type": "integer", - "default": 0, - "description": "Time to sleep (in milliseconds) between scans" - }, - "tcp_scan_timeout": { - "title": "TCP scan timeout", - "type": "integer", - "default": 3000, - "description": "Maximum time (in milliseconds) to wait for TCP response" - }, - "tcp_scan_get_banner": { - "title": "TCP scan - get banner", - "type": "boolean", - "default": True, - "description": "Determines whether the TCP scan should try to get the banner" - } - } - }, - "ping_scanner": { - "title": "Ping scanner", - "type": "object", - "properties": { - "ping_scan_timeout": { - "title": "Ping scan timeout", - "type": "integer", - "default": 1000, - "description": "Maximum time (in milliseconds) to wait for ping response" - } - } - } - } -} From bca5ad912e9be43e3c113a8898a5ab0024130ae9 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 10:41:17 +0300 Subject: [PATCH 19/40] "Exploits" config section moved to "Internal", UI fix for other moved sections --- .../services/config_schema/config_schema.py | 4 - .../cc/services/config_schema/exploits.py | 105 ------------------ .../cc/services/config_schema/internal.py | 98 ++++++++++++++++ .../configuration-components/UiSchema.js | 2 - .../ui/src/components/pages/ConfigurePage.js | 2 +- 5 files changed, 99 insertions(+), 112 deletions(-) delete mode 100644 monkey/monkey_island/cc/services/config_schema/exploits.py diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py index 91e1a686b..d1cd7a68c 100644 --- a/monkey/monkey_island/cc/services/config_schema/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -5,10 +5,8 @@ from monkey_island.cc.services.config_schema.definitions.finger_classes import F from monkey_island.cc.services.config_schema.definitions.post_breach_actions import POST_BREACH_ACTIONS from monkey_island.cc.services.config_schema.definitions.system_info_collector_classes import \ SYSTEM_INFO_COLLECTOR_CLASSES -from monkey_island.cc.services.config_schema.exploits import EXPLOITS from monkey_island.cc.services.config_schema.internal import INTERNAL from monkey_island.cc.services.config_schema.monkey import MONKEY -from monkey_island.cc.services.config_schema.network import NETWORK SCHEMA = { "title": "Monkey", @@ -25,8 +23,6 @@ SCHEMA = { "basic_network": BASIC_NETWORK, "monkey": MONKEY, "internal": INTERNAL, - "exploits": EXPLOITS, - "network": NETWORK }, "options": { "collapsed": True diff --git a/monkey/monkey_island/cc/services/config_schema/exploits.py b/monkey/monkey_island/cc/services/config_schema/exploits.py deleted file mode 100644 index acbb2f973..000000000 --- a/monkey/monkey_island/cc/services/config_schema/exploits.py +++ /dev/null @@ -1,105 +0,0 @@ -EXPLOITS = { - "title": "Exploits", - "type": "object", - "properties": { - "general": { - "title": "General", - "type": "object", - "properties": { - "skip_exploit_if_file_exist": { - "title": "Skip exploit if file exists", - "type": "boolean", - "default": False, - "description": "Determines whether the monkey should skip the exploit if the monkey's file" - " is already on the remote machine" - } - } - }, - "ms08_067": { - "title": "MS08_067", - "type": "object", - "properties": { - "ms08_067_exploit_attempts": { - "title": "MS08_067 exploit attempts", - "type": "integer", - "default": 5, - "description": "Number of attempts to exploit using MS08_067" - }, - "user_to_add": { - "title": "Remote user", - "type": "string", - "default": "Monkey_IUSER_SUPPORT", - "description": "Username to add on successful exploit" - }, - "remote_user_pass": { - "title": "Remote user password", - "type": "string", - "default": "Password1!", - "description": "Password to use for created user" - } - } - }, - "sambacry": { - "title": "SambaCry", - "type": "object", - "properties": { - "sambacry_trigger_timeout": { - "title": "SambaCry trigger timeout", - "type": "integer", - "default": 5, - "description": "Timeout (in seconds) of SambaCry trigger" - }, - "sambacry_folder_paths_to_guess": { - "title": "SambaCry folder paths to guess", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - '/', - '/mnt', - '/tmp', - '/storage', - '/export', - '/share', - '/shares', - '/home' - ], - "description": "List of full paths to share folder for SambaCry to guess" - }, - "sambacry_shares_not_to_check": { - "title": "SambaCry shares not to check", - "type": "array", - "uniqueItems": True, - "items": { - "type": "string" - }, - "default": [ - "IPC$", "print$" - ], - "description": "These shares won't be checked when exploiting with SambaCry" - } - } - }, - "smb_service": { - "title": "SMB service", - "type": "object", - "properties": { - "smb_download_timeout": { - "title": "SMB download timeout", - "type": "integer", - "default": 300, - "description": - "Timeout (in seconds) for SMB download operation (used in various exploits using SMB)" - }, - "smb_service_name": { - "title": "SMB service name", - "type": "string", - "default": "InfectionMonkey", - "description": "Name of the SMB service that will be set up to download monkey" - } - } - } - } -} diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 26ed8bc4c..4ea950232 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -354,6 +354,104 @@ INTERNAL = { "type": "string" }, "description": "List of SSH key pairs to use, when trying to ssh into servers" + }, "general": { + "title": "General", + "type": "object", + "properties": { + "skip_exploit_if_file_exist": { + "title": "Skip exploit if file exists", + "type": "boolean", + "default": False, + "description": "Determines whether the monkey should skip the exploit if the monkey's file" + " is already on the remote machine" + } + } + }, + "ms08_067": { + "title": "MS08_067", + "type": "object", + "properties": { + "ms08_067_exploit_attempts": { + "title": "MS08_067 exploit attempts", + "type": "integer", + "default": 5, + "description": "Number of attempts to exploit using MS08_067" + }, + "user_to_add": { + "title": "Remote user", + "type": "string", + "default": "Monkey_IUSER_SUPPORT", + "description": "Username to add on successful exploit" + }, + "remote_user_pass": { + "title": "Remote user password", + "type": "string", + "default": "Password1!", + "description": "Password to use for created user" + } + } + }, + "sambacry": { + "title": "SambaCry", + "type": "object", + "properties": { + "sambacry_trigger_timeout": { + "title": "SambaCry trigger timeout", + "type": "integer", + "default": 5, + "description": "Timeout (in seconds) of SambaCry trigger" + }, + "sambacry_folder_paths_to_guess": { + "title": "SambaCry folder paths to guess", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + '/', + '/mnt', + '/tmp', + '/storage', + '/export', + '/share', + '/shares', + '/home' + ], + "description": "List of full paths to share folder for SambaCry to guess" + }, + "sambacry_shares_not_to_check": { + "title": "SambaCry shares not to check", + "type": "array", + "uniqueItems": True, + "items": { + "type": "string" + }, + "default": [ + "IPC$", "print$" + ], + "description": "These shares won't be checked when exploiting with SambaCry" + } + } + } + }, + "smb_service": { + "title": "SMB service", + "type": "object", + "properties": { + "smb_download_timeout": { + "title": "SMB download timeout", + "type": "integer", + "default": 300, + "description": + "Timeout (in seconds) for SMB download operation (used in various exploits using SMB)" + }, + "smb_service_name": { + "title": "SMB service name", + "type": "string", + "default": "InfectionMonkey", + "description": "Name of the SMB service that will be set up to download monkey" + } } } }, diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 193414bdb..745b6c49e 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -60,8 +60,6 @@ export default function UiSchema(props) { } } }, - cnc: {}, - network: {}, internal: { general: { started_on_island: {'ui:widget': 'hidden'} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index ffef85739..3db5826e1 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -23,7 +23,7 @@ class ConfigurePageComponent extends AuthComponent { this.currentFormData = {}; this.initialConfig = {}; this.initialAttackConfig = {}; - this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'cnc', 'network', 'exploits', 'internal']; + this.sectionsOrder = ['attack', 'basic', 'basic_network', 'monkey', 'internal']; this.state = { schema: {}, From db6552a136b40bd06352521bb6dc88f91f93ddf3 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 10:52:05 +0300 Subject: [PATCH 20/40] Moved "victims_max_exploit" and "victims_max_find" to "internal", increased "victims_max_exploit" default to 100 --- monkey/infection_monkey/config.py | 2 +- monkey/infection_monkey/example.conf | 2 +- .../cc/services/config_schema/internal.py | 18 +++++++++++++ .../cc/services/config_schema/monkey.py | 27 +++++-------------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index b87ef9ed8..1fbcb876b 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -135,7 +135,7 @@ class Configuration(object): victims_max_find = 100 # how many victims to exploit before stopping - victims_max_exploit = 15 + victims_max_exploit = 100 # depth of propagation depth = 2 diff --git a/monkey/infection_monkey/example.conf b/monkey/infection_monkey/example.conf index 4fb0200c8..cf9d2ed70 100644 --- a/monkey/infection_monkey/example.conf +++ b/monkey/infection_monkey/example.conf @@ -99,7 +99,7 @@ ], "timeout_between_iterations": 10, "use_file_logging": true, - "victims_max_exploit": 15, + "victims_max_exploit": 100, "victims_max_find": 100, "post_breach_actions": [] custom_PBA_linux_cmd = "" diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 4ea950232..bdbae2461 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -1,3 +1,5 @@ +from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN + INTERNAL = { "title": "Internal", "type": "object", @@ -38,6 +40,22 @@ INTERNAL = { "title": "Monkey", "type": "object", "properties": { + "victims_max_find": { + "title": "Max victims to find", + "type": "integer", + "default": 100, + "description": "Determines the maximum number of machines the monkey is allowed to scan" + }, + "victims_max_exploit": { + "title": "Max victims to exploit", + "type": "integer", + "default": 100, + "description": + "Determines the maximum number of machines the monkey" + " is allowed to successfully exploit. " + WARNING_SIGN + + " Note that setting this value too high may result in the monkey propagating to " + "a high number of machines" + }, "internet_services": { "title": "Internet services", "type": "array", diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index d699da061..0f5db452f 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -93,38 +93,23 @@ MONKEY = { }, } }, - "life_cycle": { - "title": "Life cycle", + "persistent_scanning": { + "title": "Persistent scanning", "type": "object", "properties": { "max_iterations": { "title": "Max iterations", "type": "integer", "default": 1, - "description": "Determines how many iterations of the monkey's full lifecycle should occur" - }, - "victims_max_find": { - "title": "Max victims to find", - "type": "integer", - "default": 100, - "description": "Determines the maximum number of machines the monkey is allowed to scan" - }, - "victims_max_exploit": { - "title": "Max victims to exploit", - "type": "integer", - "default": 15, - "description": - "Determines the maximum number of machines the monkey" - " is allowed to successfully exploit. " + WARNING_SIGN - + " Note that setting this value too high may result in the monkey propagating to " - "a high number of machines" + "description": "Determines how many iterations of the monkey's full lifecycle should occur " + "(how many times to do the scan)" }, "timeout_between_iterations": { "title": "Wait time between iterations", "type": "integer", "default": 100, "description": - "Determines for how long (in seconds) should the monkey wait between iterations" + "Determines for how long (in seconds) should the monkey wait before starting another scan" }, "retry_failed_explotation": { "title": "Retry failed exploitation", @@ -132,7 +117,7 @@ MONKEY = { "default": True, "description": "Determines whether the monkey should retry exploiting machines" - " it didn't successfully exploit on previous iterations" + " it didn't successfully exploit on previous scans" } } } From 5449084394abbf4acba24a3a270d644d43e1ce80 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 23 Jul 2020 16:04:29 +0300 Subject: [PATCH 21/40] Added validation to important tabs (not-internal) --- monkey/common/data/validation_formats.py | 3 +++ .../services/config_schema/basic_network.py | 11 ++++++++--- .../cc/services/config_schema/monkey.py | 3 ++- .../configuration-components/UiSchema.js | 9 ++++++++- .../ValidationFormats.js | 19 +++++++++++++++++++ .../ui/src/components/pages/ConfigurePage.js | 6 ++++-- .../src/styles/pages/ConfigurationPage.scss | 4 ++++ 7 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 monkey/common/data/validation_formats.py create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js diff --git a/monkey/common/data/validation_formats.py b/monkey/common/data/validation_formats.py new file mode 100644 index 000000000..2f04dbe21 --- /dev/null +++ b/monkey/common/data/validation_formats.py @@ -0,0 +1,3 @@ +# Defined in UI on ValidationFormats.js +IP_RANGE = "ip-range" +IP = "ip" diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py index 3674c0f71..60b510e6c 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic_network.py +++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py @@ -1,3 +1,4 @@ +from common.data.validation_formats import IP, IP_RANGE from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN BASIC_NETWORK = { @@ -13,7 +14,8 @@ BASIC_NETWORK = { "type": "array", "uniqueItems": True, "items": { - "type": "string" + "type": "string", + "format": IP, }, "default": [ ], @@ -28,6 +30,7 @@ BASIC_NETWORK = { "depth": { "title": "Distance from island", "type": "integer", + "minimum": 1, "default": 2, "description": "Amount of hops allowed for the monkey to spread from the island. " @@ -39,7 +42,8 @@ BASIC_NETWORK = { "type": "array", "uniqueItems": True, "items": { - "type": "string" + "type": "string", + "format": IP_RANGE }, "default": [ ], @@ -59,7 +63,8 @@ BASIC_NETWORK = { "type": "array", "uniqueItems": True, "items": { - "type": "string" + "type": "string", + "format": IP_RANGE }, "default": [ ], diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 0f5db452f..8e0ae9439 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -1,4 +1,3 @@ -from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN from common.data.system_info_collectors_names import (AWS_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, @@ -101,6 +100,7 @@ MONKEY = { "title": "Max iterations", "type": "integer", "default": 1, + "minimum": 1, "description": "Determines how many iterations of the monkey's full lifecycle should occur " "(how many times to do the scan)" }, @@ -108,6 +108,7 @@ MONKEY = { "title": "Wait time between iterations", "type": "integer", "default": 100, + "minimum": 0, "description": "Determines for how long (in seconds) should the monkey wait before starting another scan" }, diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 745b6c49e..c11b5d4da 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -13,7 +13,14 @@ export default function UiSchema(props) { } } }, - basic_network: {}, + basic_network: { + 'ui:order': ['scope', 'network_analysis'], + scope: { + subnet_scan_list:{ + format: 'ip-list', + } + } + }, monkey: { post_breach: { post_breach_actions: { diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js new file mode 100644 index 000000000..ce605be39 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js @@ -0,0 +1,19 @@ +const ipRegex = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' +const cidrNotationRegex = '([0-9]|1[0-9]|2[0-9]|3[0-2])' + +export const formValidationFormats = { + 'ip-range': buildIpRangeRegex(), + 'ip': buildIpRegex(), +}; + +function buildIpRangeRegex(){ + return new RegExp([ + '^'+ipRegex+'$|', // Single IP + '^'+ipRegex+'-'+ipRegex+'$|', // IP range IP-IP + '^'+ipRegex+'/'+cidrNotationRegex+'$' // IP range with cidr notation: IP/cidr + ].join('')) +} + +function buildIpRegex(){ + return new RegExp('^'+ipRegex+'$') +} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 3db5826e1..7bc2a919e 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -9,6 +9,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; +import {formValidationFormats} from "../configuration-components/ValidationFormats"; const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; @@ -342,8 +343,9 @@ class ConfigurePageComponent extends AuthComponent { })} formData={this.state.configuration[this.state.selectedSection]} onChange={this.onChange} - noValidate={true} - className={'config-form'}> + customFormats={formValidationFormats} + className={'config-form'} + liveValidate>
) diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index 48b168476..0947a1540 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -31,6 +31,10 @@ margin-left: 2em; } +.config-form div.card.errors { + display: none; +} + .config-template-no-header > p { display: none; } From 336c3cbb47e4431f91085d730514d4fdb8628e0c Mon Sep 17 00:00:00 2001 From: Shay Nehmad Date: Thu, 23 Jul 2020 18:18:53 +0300 Subject: [PATCH 22/40] Update descriptions of config values Now can use whitespace --- .../cc/services/config_schema/basic.py | 7 +++- .../services/config_schema/basic_network.py | 39 +++++++++++-------- .../configuration-components/UiSchema.js | 2 +- .../src/styles/pages/ConfigurationPage.scss | 5 +++ 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/basic.py b/monkey/monkey_island/cc/services/config_schema/basic.py index 6a255fc95..b141db010 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic.py +++ b/monkey/monkey_island/cc/services/config_schema/basic.py @@ -6,6 +6,7 @@ BASIC = { "exploiters": { "title": "Exploiters", "type": "object", + "description": "Choose which exploiters the Monkey will attempt.", "properties": { "exploiter_classes": { "title": "Exploiters", @@ -46,7 +47,8 @@ BASIC = { "root", "user" ], - "description": "List of usernames to use on exploits using credentials" + "description": "List of user names that will be used by exploiters that need credentials, like " + "SSH brute-forcing." }, "exploit_password_list": { "title": "Exploit password list", @@ -61,7 +63,8 @@ BASIC = { "password", "12345678" ], - "description": "List of password to use on exploits using credentials" + "description": "List of passwords that will be used by exploiters that need credentials, like " + "SSH brute-forcing." } } } diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py index 3674c0f71..fb9d0af24 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic_network.py +++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py @@ -17,25 +17,26 @@ BASIC_NETWORK = { }, "default": [ ], - "description": "List of IPs to not scan" + "description": "List of IPs that the Monkey will not scan." }, "local_network_scan": { "title": "Local network scan", "type": "boolean", "default": True, - "description": "Determines whether the monkey should scan its subnets additionally" + "description": "Determines whether the monkey will scan the local subnets of machines it runs on, in " + "addition to the IPs that are configured manually in the 'scan target list'." }, "depth": { "title": "Distance from island", "type": "integer", "default": 2, "description": - "Amount of hops allowed for the monkey to spread from the island. " + "Amount of hops allowed for the monkey to spread from the island. \n" + WARNING_SIGN - + " Note that setting this value too high may result in the monkey propagating too far" + + " Note that setting this value too high may result in the monkey propagating too far." }, "subnet_scan_list": { - "title": "Scan IP/subnet list", + "title": "Scan target list", "type": "array", "uniqueItems": True, "items": { @@ -44,9 +45,12 @@ BASIC_NETWORK = { "default": [ ], "description": - "List of IPs/subnets/hosts the monkey should scan." - " Examples: \"192.168.0.1\", \"192.168.0.5-192.168.0.20\", \"192.168.0.5/24\"," - " \"printer.example\"" + "List of targets the Monkey will try to scan. The targets can be IPs, subnets or hosts." + " Examples:\n" + "\tTarget a specific IP: \"192.168.0.1\"\n" + "\tTarget a subnet using a network range: \"192.168.0.5-192.168.0.20\"\n" + "\tTarget a subnet using an IP mask: \"192.168.0.5/24\"\n" + "\tTarget a specific host: \"printer.example\"" } } }, @@ -64,14 +68,17 @@ BASIC_NETWORK = { "default": [ ], "description": - "Test for network segmentation by providing a list of" - " subnets that should NOT be accessible to each other." - " For example, given the following configuration:" - " '10.0.0.0/24, 11.0.0.2/32, 12.2.3.0/24'" - " a Monkey running on 10.0.0.5 will try to access machines in the following" - " subnets: 11.0.0.2/32, 12.2.3.0/24." - " An alert on successful connections will be shown in the report" - " Additional subnet formats include: 13.0.0.1, 13.0.0.1-13.0.0.5" + "Test for network segmentation by providing a list of network segments that should NOT be accessible " + "to each other.\n\n" + "For example, if you configured the following three segments: \"10.0.0.0/24\", \"11.0.0.2/32\", " + "and \"12.2.3.0/24\", a Monkey running on 10.0.0.5 will try to access machines in the following " + "subnets: 11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections will be shown in the " + "reports. \n\n" + "Network segments can be IPs, subnets or hosts. Examples:\n" + "\tDefine a single-IP segment: \"192.168.0.1\"\n" + "\tDefine a segment using a network range: \"192.168.0.5-192.168.0.20\"\n" + "\tDefine a segment using an subnet IP mask: \"192.168.0.5/24\"\n" + "\tDefine a single-host segment: \"printer.example\"" } } } diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 745b6c49e..a8425b5ae 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -76,6 +76,6 @@ export default function UiSchema(props) { } } } - } + }; return UiSchema[props.selectedSection] } diff --git a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss index 48b168476..de19a5d9e 100644 --- a/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss +++ b/monkey/monkey_island/cc/ui/src/styles/pages/ConfigurationPage.scss @@ -48,3 +48,8 @@ .config-field-hidden { display: none; } + +.field-description { + white-space: pre-wrap; +} + From c9468b8600ae75d3698570108f6af5ad6148239c Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 09:18:56 +0300 Subject: [PATCH 23/40] Changed empty checkbox UI to unfilled in AdvancedMultiSelect.js --- .../ui/src/components/ui-components/AdvancedMultiSelect.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js index 03b4935f2..9c1468d8d 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/AdvancedMultiSelect.js @@ -2,7 +2,8 @@ import React, {useState} from 'react'; import {Card, Button, Form} from 'react-bootstrap'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {faSquare, faCheckSquare} from '@fortawesome/free-solid-svg-icons'; +import {faCheckSquare} from '@fortawesome/free-solid-svg-icons'; +import {faSquare} from '@fortawesome/free-regular-svg-icons'; import {cloneDeep} from 'lodash'; import {getComponentHeight} from './utils/HeightCalculator'; @@ -37,7 +38,7 @@ function getFullDefinitionsFromRegistry(refString, registry) { function getObjectFromRegistryByRef(refString, registry) { let refArray = refString.replace('#', '').split('/'); - return resolveObjectPath(refArray, registry); + return resolveObjectPath(refArray, registry); } function getFullDefinitionByKey(refString, registry, itemKey) { @@ -50,7 +51,7 @@ function setPaneInfo(refString, registry, itemKey, setPaneInfoFnc) { setPaneInfoFnc({title: definitionObj.title, content: definitionObj.info, link: definitionObj.link}); } -function getDefaultPaneParams(refString, registry){ +function getDefaultPaneParams(refString, registry) { let configSection = getObjectFromRegistryByRef(refString, registry); return ({title: configSection.title, content: configSection.description}); } From 696dd83ef682a901e2dbec0cce4403a8001ad4a9 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 09:45:17 +0300 Subject: [PATCH 24/40] Changed exploiter documentation links in config --- .../definitions/exploiter_classes.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py index 0b9e97fa1..604ba2073 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/exploiter_classes.py @@ -15,7 +15,7 @@ EXPLOITER_CLASSES = { "attack_techniques": ["T1110", "T1075", "T1035"], "info": "Brute forces using credentials provided by user and" " hashes gathered by mimikatz.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/smbexec/" }, { "type": "string", @@ -26,7 +26,7 @@ EXPLOITER_CLASSES = { "attack_techniques": ["T1110", "T1106"], "info": "Brute forces WMI (Windows Management Instrumentation) " "using credentials provided by user and hashes gathered by mimikatz.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/wmiexec/" }, { "type": "string", @@ -37,7 +37,7 @@ EXPLOITER_CLASSES = { "attack_techniques": ["T1110"], "info": "Tries to brute force into MsSQL server and uses insecure " "configuration to execute commands on server.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/mssql/" }, { "type": "string", @@ -47,7 +47,7 @@ EXPLOITER_CLASSES = { "title": "MS08-067 Exploiter (UNSAFE)", "info": "Unsafe exploiter, that might cause system crash due to the use of buffer overflow. " "Uses MS08-067 vulnerability.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/ms08-067/" }, { "type": "string", @@ -57,7 +57,7 @@ EXPLOITER_CLASSES = { "title": "SSH Exploiter", "attack_techniques": ["T1110", "T1145", "T1106"], "info": "Brute forces using credentials provided by user and SSH keys gathered from systems.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sshexec/" }, { "type": "string", @@ -67,7 +67,7 @@ EXPLOITER_CLASSES = { "title": "ShellShock Exploiter", "info": "CVE-2014-6271, based on logic from " "https://github.com/nccgroup/shocker/blob/master/shocker.py .", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/shellshock/" }, { "type": "string", @@ -76,7 +76,7 @@ EXPLOITER_CLASSES = { ], "title": "SambaCry Exploiter", "info": "Bruteforces and searches for anonymous shares. Uses Impacket.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/sambacry/" }, { "type": "string", @@ -85,7 +85,7 @@ EXPLOITER_CLASSES = { ], "title": "ElasticGroovy Exploiter", "info": "CVE-2015-1427. Logic is based on Metasploit module.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/elasticgroovy/" }, { "type": "string", @@ -95,7 +95,7 @@ EXPLOITER_CLASSES = { "title": "Struts2 Exploiter", "info": "Exploits struts2 java web framework. CVE-2017-5638. Logic based on " "https://www.exploit-db.com/exploits/41570 .", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/struts2/" }, { "type": "string", @@ -104,7 +104,7 @@ EXPLOITER_CLASSES = { ], "title": "WebLogic Exploiter", "info": "Exploits CVE-2017-10271 and CVE-2019-2725 vulnerabilities on WebLogic server.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/weblogic/" }, { "type": "string", @@ -114,7 +114,7 @@ EXPLOITER_CLASSES = { "title": "Hadoop/Yarn Exploiter", "info": "Remote code execution on HADOOP server with YARN and default settings. " "Logic based on https://github.com/vulhub/vulhub/tree/master/hadoop/unauthorized-yarn.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/hadoop/" }, { "type": "string", @@ -124,7 +124,7 @@ EXPLOITER_CLASSES = { "title": "VSFTPD Exploiter", "info": "Exploits a malicious backdoor that was added to the VSFTPD download archive. " "Logic based on Metasploit module.", - "link": "https://github.com/guardicore/monkey/wiki/Exploiters" + "link": "https://www.guardicore.com/infectionmonkey/docs/reference/exploiters/vsftpd/" } ] } From cc78076d32ee3b83550eb721c280526d83ff9ab5 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 10:45:33 +0300 Subject: [PATCH 25/40] Added hostname's to IP range validation --- .../components/configuration-components/ValidationFormats.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js index ce605be39..db2bcb29c 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js @@ -1,5 +1,6 @@ const ipRegex = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' const cidrNotationRegex = '([0-9]|1[0-9]|2[0-9]|3[0-2])' +const hostnameRegex = '^([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*)$' export const formValidationFormats = { 'ip-range': buildIpRangeRegex(), @@ -10,7 +11,8 @@ function buildIpRangeRegex(){ return new RegExp([ '^'+ipRegex+'$|', // Single IP '^'+ipRegex+'-'+ipRegex+'$|', // IP range IP-IP - '^'+ipRegex+'/'+cidrNotationRegex+'$' // IP range with cidr notation: IP/cidr + '^'+ipRegex+'/'+cidrNotationRegex+'$|', // IP range with cidr notation: IP/cidr + hostnameRegex, // IP range with cidr notation: IP/cidr ].join('')) } From a1c11df50ba7660385673bf33e0e2804c360afb0 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 11:20:42 +0300 Subject: [PATCH 26/40] Added descriptions to post breach actions, where it was missing --- .../config_schema/definitions/post_breach_actions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py index 9e55ee5ba..f3e2a9bfa 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py @@ -48,6 +48,8 @@ POST_BREACH_ACTIONS = { "TrapCommand" ], "title": "Trap", + "info": "On Linux systems, attempts to trap an interrupt signal in order to execute a command " + "upon receiving that signal. Removes the trap afterwards.", "attack_techniques": ["T1154"] }, { @@ -56,6 +58,8 @@ POST_BREACH_ACTIONS = { "ChangeSetuidSetgid" ], "title": "Setuid and Setgid", + "info": "On Linux systems, attempts to set the setuid and setgid bits of a new file. " + "Removes the file afterwards.", "attack_techniques": ["T1166"] }, { @@ -64,6 +68,7 @@ POST_BREACH_ACTIONS = { "ScheduleJobs" ], "title": "Job scheduling", + "info": "Attempts to create a scheduled job on the system and remove it.", "attack_techniques": ["T1168", "T1053"] } ] From 09734df93dd7a403e402e038a9ec89ba4f63f695 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 11:21:39 +0300 Subject: [PATCH 27/40] Fixed double (( typo in WMI exploiter documentation --- docs/content/reference/exploiters/WMIExec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/exploiters/WMIExec.md b/docs/content/reference/exploiters/WMIExec.md index 490c33fcf..346bc6eed 100644 --- a/docs/content/reference/exploiters/WMIExec.md +++ b/docs/content/reference/exploiters/WMIExec.md @@ -5,4 +5,4 @@ draft: false tags: ["exploit", "windows"] --- -Brute forces WMI (Windows Management Instrumentation) using credentials provided by user ((see ["Configuration"](../usage/configuration))) and hashes gathered by mimikatz. +Brute forces WMI (Windows Management Instrumentation) using credentials provided by user (see ["Configuration"](../usage/configuration)) and hashes gathered by mimikatz. From cf45ec940138fb65d92d0e86cbd6f3fb50e4e785 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 12:40:06 +0300 Subject: [PATCH 28/40] Typo fixes and improvements --- .../services/config_schema/basic_network.py | 26 ++++++++++--------- .../ui/src/components/pages/ConfigurePage.js | 4 +-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py index 21a525220..0fd3344e8 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic_network.py +++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py @@ -25,18 +25,19 @@ BASIC_NETWORK = { "title": "Local network scan", "type": "boolean", "default": True, - "description": "Determines whether the monkey will scan the local subnets of machines it runs on, in " - "addition to the IPs that are configured manually in the 'scan target list'." + "description": "Determines whether the Monkey will scan the local subnets of machines it runs on, " + "in addition to the IPs that are configured manually in the \"Scan target list\"." }, "depth": { - "title": "Distance from island", + "title": "Scan depth", "type": "integer", "minimum": 1, "default": 2, "description": - "Amount of hops allowed for the monkey to spread from the island. \n" + "Amount of hops allowed for the Monkey to spread from the Island server. \n" + WARNING_SIGN - + " Note that setting this value too high may result in the monkey propagating too far." + + " Note that setting this value too high may result in the Monkey propagating too far, " + "if the \"Local network scan\" is enabled." }, "subnet_scan_list": { "title": "Scan target list", @@ -49,7 +50,7 @@ BASIC_NETWORK = { "default": [ ], "description": - "List of targets the Monkey will try to scan. The targets can be IPs, subnets or hosts." + "List of targets the Monkey will try to scan. Targets can be IPs, subnets or hosts." " Examples:\n" "\tTarget a specific IP: \"192.168.0.1\"\n" "\tTarget a subnet using a network range: \"192.168.0.5-192.168.0.20\"\n" @@ -73,12 +74,13 @@ BASIC_NETWORK = { "default": [ ], "description": - "Test for network segmentation by providing a list of network segments that should NOT be accessible " - "to each other.\n\n" - "For example, if you configured the following three segments: \"10.0.0.0/24\", \"11.0.0.2/32\", " - "and \"12.2.3.0/24\", a Monkey running on 10.0.0.5 will try to access machines in the following " - "subnets: 11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections will be shown in the " - "reports. \n\n" + "Test for network segmentation by providing a list of network segments " + "that should NOT be accessible to each other.\n\n" + "For example, if you configured the following three segments: " + "\"10.0.0.0/24\", \"11.0.0.2/32\", and \"12.2.3.0/24\", " + "a Monkey running on 10.0.0.5 will try to access machines in the following subnets: " + "11.0.0.2/32, 12.2.3.0/24. An alert on successful cross-segment connections " + "will be shown in the reports. \n\n" "Network segments can be IPs, subnets or hosts. Examples:\n" "\tDefine a single-IP segment: \"192.168.0.1\"\n" "\tDefine a segment using a network range: \"192.168.0.5-192.168.0.20\"\n" diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 7bc2a919e..0fe3251eb 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -371,8 +371,8 @@ class ConfigurePageComponent extends AuthComponent { if (this.state.selectedSection === 'basic_network') { return (
- The Monkey scans its subnet if 'Local network scan' is ticked. Additionally the monkey scans machines - according to its range class. + The Monkey scans its subnet if "Local network scan" is ticked. Additionally the monkey scans machines + according to "Scan target list".
) } else { return (
) From 76401f077825ba8f5cf45aebda78926ea8f84540 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 12:41:07 +0300 Subject: [PATCH 29/40] Rolled back server_config.json to a clean one --- monkey/monkey_island/cc/server_config.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/monkey/monkey_island/cc/server_config.json b/monkey/monkey_island/cc/server_config.json index 708b5c29c..ecc4c1708 100644 --- a/monkey/monkey_island/cc/server_config.json +++ b/monkey/monkey_island/cc/server_config.json @@ -1,6 +1,4 @@ { "server_config": "password", - "deployment": "develop", - "user": "test", - "password_hash": "9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7b710110c0a678288166e7fbe796883a4f2e9b3ca9f484f521d0ce464345cc1aec96779149c14" -} \ No newline at end of file + "deployment": "develop" +} From ecea415e360c3292526304ccc8af744f14fde46f Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 17:00:08 +0300 Subject: [PATCH 30/40] Separated InternalConfig into separate tabs for easier navigation --- .../InternalConfig.js | 69 +++++++++++++++++++ .../ui/src/components/pages/ConfigurePage.js | 56 ++++++++------- 2 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js new file mode 100644 index 000000000..feedd533f --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js @@ -0,0 +1,69 @@ +import Form from 'react-jsonschema-form-bs4'; +import React, {useState} from 'react'; +import {Nav} from 'react-bootstrap'; + +const sectionOrder = ['network', 'monkey', 'island_server', 'logging', 'exploits', 'dropper', 'classes', 'general', + 'kill_file', 'testing']; +const initialSection = sectionOrder[0]; + +export default function InternalConfig(props) { + const { + schema, + uiSchema, + onChange, + customFormats, + className, + formData + } = props; + const [selectedSection, setSelectedSection] = useState(initialSection); + const [displayedSchema, setDisplayedSchema] = useState(getSchemaByKey(schema, initialSection)); + const [displayedSchemaUi, setDisplayedSchemaUi] = useState(uiSchema[initialSection]) + + const onInnerDataChange = (innerData) => { + formData[selectedSection] = innerData.formData; + onChange({formData: formData}); + } + + const setSection = (sectionKey) => { + setSelectedSection(sectionKey); + setDisplayedSchema(getSchemaByKey(schema, sectionKey)); + setDisplayedSchemaUi(uiSchema[sectionKey]) + } + + const renderNav = () => { + return () + } + + return (
+ {renderNav()} +
+ +
+
) +}; + +function getSchemaByKey(schema, key) { + let definitions = schema['definitions'] + return {definitions: definitions, properties: schema['properties'][key]['properties']} +} + +function getNavTitle(schema, key) { + return schema.properties[key].title; +} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 0fe3251eb..97e1056b9 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -10,6 +10,7 @@ import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; import {formValidationFormats} from "../configuration-components/ValidationFormats"; +import InternalConfig from "../configuration-components/InternalConfig"; const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; @@ -244,8 +245,8 @@ class ConfigurePageComponent extends AuthComponent { this.props.onStatusChange(); } ).then(() => { - this.removePBAfile(API_PBA_WINDOWS, this.setPbaFilenameWindows) - this.removePBAfile(API_PBA_LINUX, this.setPbaFilenameLinux) + this.removePBAfile(API_PBA_WINDOWS, this.setPbaFilenameWindows) + this.removePBAfile(API_PBA_LINUX, this.setPbaFilenameLinux) }); this.authFetch(ATTACK_URL, { method: 'POST', @@ -331,24 +332,33 @@ class ConfigurePageComponent extends AuthComponent { }; renderConfigContent = (displayedSchema) => { - return (
- {this.renderBasicNetworkWarning()} -
- -
-
) + let formProperties = {}; + formProperties['schema'] = displayedSchema + formProperties['uiSchema'] = UiSchema({ + PBA_linux_filename: this.state.configuration.monkey.post_breach.PBA_linux_filename, + PBA_windows_filename: this.state.configuration.monkey.post_breach.PBA_windows_filename, + setPbaFilenameWindows: this.setPbaFilenameWindows, + setPbaFilenameLinux: this.setPbaFilenameLinux, + selectedSection: this.state.selectedSection + }) + formProperties['formData'] = this.state.configuration[this.state.selectedSection] + formProperties['onChange'] = this.onChange + formProperties['customFormats'] = formValidationFormats + formProperties['className'] = 'config-form' + formProperties['liveValidate'] = true + + if (this.state.selectedSection === 'internal') { + return () + } else { + return ( +
+ {this.renderBasicNetworkWarning()} +
+ +
+
+ ) + } }; setPbaFilenameWindows = (filename) => { @@ -388,9 +398,9 @@ class ConfigurePageComponent extends AuthComponent { {this.state.sections.map(section => { let classProp = section.key.startsWith('basic') ? 'tab-primary' : ''; return ( - - {section.title} - ); + + {section.title} + ); })} ) }; From b366d12c99053cb3c59d75ee75b2d19fdecb8557 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 17:17:38 +0300 Subject: [PATCH 31/40] Linting fixes --- .../configuration-components/InternalConfig.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js index feedd533f..abb0230a2 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js @@ -17,7 +17,7 @@ export default function InternalConfig(props) { } = props; const [selectedSection, setSelectedSection] = useState(initialSection); const [displayedSchema, setDisplayedSchema] = useState(getSchemaByKey(schema, initialSection)); - const [displayedSchemaUi, setDisplayedSchemaUi] = useState(uiSchema[initialSection]) + const [displayedSchemaUi, setDisplayedSchemaUi] = useState(uiSchema[initialSection]); const onInnerDataChange = (innerData) => { formData[selectedSection] = innerData.formData; @@ -27,7 +27,7 @@ export default function InternalConfig(props) { const setSection = (sectionKey) => { setSelectedSection(sectionKey); setDisplayedSchema(getSchemaByKey(schema, sectionKey)); - setDisplayedSchemaUi(uiSchema[sectionKey]) + setDisplayedSchemaUi(uiSchema[sectionKey]); } const renderNav = () => { @@ -57,11 +57,11 @@ export default function InternalConfig(props) {
) -}; +} function getSchemaByKey(schema, key) { - let definitions = schema['definitions'] - return {definitions: definitions, properties: schema['properties'][key]['properties']} + let definitions = schema['definitions']; + return {definitions: definitions, properties: schema['properties'][key]['properties']}; } function getNavTitle(schema, key) { From 49825d460b9c07188de001ff2e783d0fe2dedd34 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 17:20:24 +0300 Subject: [PATCH 32/40] Bugfix in HeightCalculator.js --- .../ui/src/components/ui-components/utils/HeightCalculator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js index 1dcd47516..65a4fa178 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/utils/HeightCalculator.js @@ -6,7 +6,7 @@ export function getComponentHeight(subcomponentCount, subcomponentHeight = defaultSubcomponentHeight, minHeight = defaultMinHeight, maxHeight = defaultMaxHeight) { - let height = defaultMinHeight + (subcomponentHeight*subcomponentCount); + let height = minHeight + (subcomponentHeight*subcomponentCount); if (height > maxHeight) height = maxHeight From 951794a707b913e9c716f2f03dda7a154192d186 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Fri, 24 Jul 2020 17:23:53 +0300 Subject: [PATCH 33/40] More linting fixes --- .../ui/src/components/configuration-components/UiSchema.js | 6 +++--- .../cc/ui/src/components/pages/ConfigurePage.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 18824fb7b..914d23ed3 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -1,5 +1,5 @@ -import AdvancedMultiSelect from "../ui-components/AdvancedMultiSelect"; -import PbaInput from "./PbaInput"; +import AdvancedMultiSelect from '../ui-components/AdvancedMultiSelect'; +import PbaInput from './PbaInput'; import {API_PBA_LINUX, API_PBA_WINDOWS} from '../pages/ConfigurePage'; export default function UiSchema(props) { @@ -17,7 +17,7 @@ export default function UiSchema(props) { 'ui:order': ['scope', 'network_analysis'], scope: { subnet_scan_list:{ - format: 'ip-list', + format: 'ip-list' } } }, diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 97e1056b9..e7ef099e5 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -9,8 +9,8 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; -import {formValidationFormats} from "../configuration-components/ValidationFormats"; -import InternalConfig from "../configuration-components/InternalConfig"; +import {formValidationFormats} from '../configuration-components/ValidationFormats'; +import InternalConfig from '../configuration-components/InternalConfig'; const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; @@ -264,7 +264,7 @@ class ConfigurePageComponent extends AuthComponent { removePBAfile(apiEndpoint, setFilenameFnc) { this.sendPbaRemoveRequest(apiEndpoint) - setFilenameFnc("") + setFilenameFnc('') } sendPbaRemoveRequest(apiEndpoint) { From 0deb8c63c52f343ab0527b2bd030b640a1cffa0a Mon Sep 17 00:00:00 2001 From: Shay Nehmad Date: Sun, 26 Jul 2020 11:21:57 +0300 Subject: [PATCH 34/40] Fix import formatting --- monkey/monkey_island/cc/services/config.py | 1 - .../cc/services/config_schema/config_schema.py | 9 ++++++--- .../definitions/system_info_collector_classes.py | 4 ++-- monkey/monkey_island/cc/services/config_schema/monkey.py | 4 +++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/monkey/monkey_island/cc/services/config.py b/monkey/monkey_island/cc/services/config.py index 341297435..ac1ee1417 100644 --- a/monkey/monkey_island/cc/services/config.py +++ b/monkey/monkey_island/cc/services/config.py @@ -10,7 +10,6 @@ import monkey_island.cc.services.post_breach_files from monkey_island.cc.database import mongo from monkey_island.cc.encryptor import encryptor from monkey_island.cc.network_utils import local_ip_addresses - from monkey_island.cc.services.config_schema.config_schema import SCHEMA __author__ = "itay.mizeretz" diff --git a/monkey/monkey_island/cc/services/config_schema/config_schema.py b/monkey/monkey_island/cc/services/config_schema/config_schema.py index d1cd7a68c..04e586e71 100644 --- a/monkey/monkey_island/cc/services/config_schema/config_schema.py +++ b/monkey/monkey_island/cc/services/config_schema/config_schema.py @@ -1,8 +1,11 @@ from monkey_island.cc.services.config_schema.basic import BASIC from monkey_island.cc.services.config_schema.basic_network import BASIC_NETWORK -from monkey_island.cc.services.config_schema.definitions.exploiter_classes import EXPLOITER_CLASSES -from monkey_island.cc.services.config_schema.definitions.finger_classes import FINGER_CLASSES -from monkey_island.cc.services.config_schema.definitions.post_breach_actions import POST_BREACH_ACTIONS +from monkey_island.cc.services.config_schema.definitions.exploiter_classes import \ + EXPLOITER_CLASSES +from monkey_island.cc.services.config_schema.definitions.finger_classes import \ + FINGER_CLASSES +from monkey_island.cc.services.config_schema.definitions.post_breach_actions import \ + POST_BREACH_ACTIONS from monkey_island.cc.services.config_schema.definitions.system_info_collector_classes import \ SYSTEM_INFO_COLLECTOR_CLASSES from monkey_island.cc.services.config_schema.internal import INTERNAL diff --git a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py index 8b960d1d8..5f113f4a7 100644 --- a/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py +++ b/monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py @@ -1,9 +1,9 @@ from common.data.system_info_collectors_names import (AWS_COLLECTOR, + AZURE_CRED_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, - AZURE_CRED_COLLECTOR) + PROCESS_LIST_COLLECTOR) SYSTEM_INFO_COLLECTOR_CLASSES = { "title": "System Information Collectors", diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index 8e0ae9439..dd10cb35b 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -1,7 +1,9 @@ from common.data.system_info_collectors_names import (AWS_COLLECTOR, + AZURE_CRED_COLLECTOR, ENVIRONMENT_COLLECTOR, HOSTNAME_COLLECTOR, - PROCESS_LIST_COLLECTOR, MIMIKATZ_COLLECTOR, AZURE_CRED_COLLECTOR) + MIMIKATZ_COLLECTOR, + PROCESS_LIST_COLLECTOR) MONKEY = { "title": "Monkey", From e21d67c37ac22f4efd86224e0ca2a738ad809521 Mon Sep 17 00:00:00 2001 From: Shay Nehmad Date: Sun, 26 Jul 2020 14:40:13 +0300 Subject: [PATCH 35/40] Clean some JS warnings --- .travis.yml | 2 +- monkey/monkey_island/cc/ui/.eslintrc | 2 +- .../monkey_island/cc/ui/src/components/Main.js | 2 +- .../cc/ui/src/components/SideNavComponent.js | 2 +- .../ui/src/components/attack/techniques/T1136.js | 2 +- .../configuration-components/InternalConfig.js | 16 +++++++++++++--- .../configuration-components/PbaInput.js | 6 +++--- .../ValidationFormats.js | 4 ++-- .../components/map/preview-pane/PreviewPane.js | 4 ++-- .../cc/ui/src/components/pages/ConfigurePage.js | 4 ++-- .../cc/ui/src/components/pages/LicensePage.js | 4 ++-- .../cc/ui/src/components/pages/LoginPage.js | 6 +++--- .../cc/ui/src/components/pages/MapPage.js | 2 +- .../cc/ui/src/components/pages/RunMonkeyPage.js | 4 ++-- .../cc/ui/src/components/pages/StartOverPage.js | 4 ++-- .../cc/ui/src/components/pages/TelemetryPage.js | 2 +- .../components/report-components/AttackReport.js | 2 +- .../report-components/SecurityReport.js | 2 +- .../common/MonkeysStillAliveWarning.js | 2 +- .../common/MustRunMonkeyWarning.js | 2 +- .../common/PrintReportButton.js | 2 +- .../report-components/common/RenderArrays.js | 2 +- .../security/BreachedServers.js | 2 +- .../report-components/security/PostBreach.js | 4 ++-- .../report-components/security/ScannedServers.js | 4 ++-- .../report-components/security/StrongUsers.js | 2 +- .../report-components/zerotrust/FindingsTable.js | 8 ++++++-- .../zerotrust/PrinciplesStatusTable.js | 8 ++++++-- .../report-components/zerotrust/ReportLegend.js | 2 +- .../zerotrust/SinglePillarPrinciplesStatus.js | 2 +- .../zerotrust/venn-components/VennDiagram.js | 2 +- .../ui/src/components/run-monkey/AwsRunTable.js | 2 +- .../ui/src/components/ui-components/InfoPane.js | 4 ++-- .../ui-components/MissingBinariesModal.js | 1 - 34 files changed, 68 insertions(+), 51 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5228275d4..62bec4fd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -83,7 +83,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=70 +- JS_WARNINGS_AMOUNT_UPPER_LIMIT=25 - eslint ./src --max-warnings $JS_WARNINGS_AMOUNT_UPPER_LIMIT # Test for max warnings # Build documentation diff --git a/monkey/monkey_island/cc/ui/.eslintrc b/monkey/monkey_island/cc/ui/.eslintrc index 3cdf79db7..2cd52bb98 100644 --- a/monkey/monkey_island/cc/ui/.eslintrc +++ b/monkey/monkey_island/cc/ui/.eslintrc @@ -41,7 +41,7 @@ "global-strict": 0, "no-underscore-dangle": 0, "no-console": 0, - "no-unused-vars": 1, + "no-unused-vars": [1, {"vars": "all", "args": "all", "argsIgnorePattern": "^_", "varsIgnorePattern": "^React$" }], "no-trailing-spaces": [ 1, { diff --git a/monkey/monkey_island/cc/ui/src/components/Main.js b/monkey/monkey_island/cc/ui/src/components/Main.js index 6a3f18a5a..7ef373f05 100644 --- a/monkey/monkey_island/cc/ui/src/components/Main.js +++ b/monkey/monkey_island/cc/ui/src/components/Main.js @@ -97,7 +97,7 @@ class AppComponent extends AuthComponent { }; redirectTo = (userPath, targetPath) => { - let pathQuery = new RegExp(userPath + '[\/]?$', 'g'); + let pathQuery = new RegExp(userPath + '[/]?$', 'g'); if (window.location.pathname.match(pathQuery)) { return } diff --git a/monkey/monkey_island/cc/ui/src/components/SideNavComponent.js b/monkey/monkey_island/cc/ui/src/components/SideNavComponent.js index 373d07fd3..52fb3fb4e 100644 --- a/monkey/monkey_island/cc/ui/src/components/SideNavComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/SideNavComponent.js @@ -49,7 +49,7 @@ class SideNavComponent extends React.Component {
  • { + isActive={(_match, location) => { return (location.pathname === '/report/attack' || location.pathname === '/report/zeroTrust' || location.pathname === '/report/security') diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1136.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1136.js index 55cd9966c..2df34c454 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1136.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1136.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactTable from 'react-table'; import {renderMachineFromSystemData, ScanStatus} from './Helpers'; -import MitigationsComponent from "./MitigationsComponent"; +import MitigationsComponent from './MitigationsComponent'; class T1136 extends React.Component { diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js index abb0230a2..784931cbb 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js @@ -2,8 +2,18 @@ import Form from 'react-jsonschema-form-bs4'; import React, {useState} from 'react'; import {Nav} from 'react-bootstrap'; -const sectionOrder = ['network', 'monkey', 'island_server', 'logging', 'exploits', 'dropper', 'classes', 'general', - 'kill_file', 'testing']; +const sectionOrder = [ + 'network', + 'monkey', + 'island_server', + 'logging', + 'exploits', + 'dropper', + 'classes', + 'general', + 'kill_file', + 'testing' +]; const initialSection = sectionOrder[0]; export default function InternalConfig(props) { @@ -38,7 +48,7 @@ export default function InternalConfig(props) { className={'config-nav'}> {sectionOrder.map(section => { return ( - + {getNavTitle(schema, section)} ); })} diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js index f341a085e..507173b6f 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/PbaInput.js @@ -23,8 +23,8 @@ class PbaInput extends AuthComponent { }; } - componentDidUpdate(prevProps, prevState, snapshot) { - if(prevProps.options.filename !== this.props.options.filename && this.props.options.filename === ""){ + componentDidUpdate(prevProps, _prevState, _snapshot) { + if(prevProps.options.filename !== this.props.options.filename && this.props.options.filename === ''){ this.setState({filename: this.props.options.filename}) } } @@ -68,7 +68,7 @@ class PbaInput extends AuthComponent { if (fileItems.length > 0) { this.state.setPbaFilename(fileItems[0].file.name) } else { - this.state.setPbaFilename("") + this.state.setPbaFilename('') } }} />) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js index db2bcb29c..f38ddda0d 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js @@ -4,7 +4,7 @@ const hostnameRegex = '^([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za export const formValidationFormats = { 'ip-range': buildIpRangeRegex(), - 'ip': buildIpRegex(), + 'ip': buildIpRegex() }; function buildIpRangeRegex(){ @@ -12,7 +12,7 @@ function buildIpRangeRegex(){ '^'+ipRegex+'$|', // Single IP '^'+ipRegex+'-'+ipRegex+'$|', // IP range IP-IP '^'+ipRegex+'/'+cidrNotationRegex+'$|', // IP range with cidr notation: IP/cidr - hostnameRegex, // IP range with cidr notation: IP/cidr + hostnameRegex // IP range with cidr notation: IP/cidr ].join('')) } diff --git a/monkey/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js b/monkey/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js index 84443ec75..27800cb97 100644 --- a/monkey/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js +++ b/monkey/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js @@ -101,9 +101,9 @@ class PreviewPaneComponent extends AuthComponent { .replace(/\\t/g, '\t') .replace(/\\b/g, '\b') .replace(/\\f/g, '\f') - .replace(/\\"/g, '\"') + .replace(/\\"/g, '"') .replace(/\\'/g, '\'') - .replace(/\\&/g, '\&'); + .replace(/\\&/g, '&'); } downloadLog(asset) { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index e7ef099e5..abf98d6c6 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -34,7 +34,7 @@ class ConfigurePageComponent extends AuthComponent { lastAction: 'none', sections: [], selectedSection: 'attack', - showAttackAlert: false, + showAttackAlert: false }; } @@ -398,7 +398,7 @@ class ConfigurePageComponent extends AuthComponent { {this.state.sections.map(section => { let classProp = section.key.startsWith('basic') ? 'tab-primary' : ''; return ( - + {section.title} ); })} diff --git a/monkey/monkey_island/cc/ui/src/components/pages/LicensePage.js b/monkey/monkey_island/cc/ui/src/components/pages/LicensePage.js index 3fc29649b..bbc05a12f 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/LicensePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/LicensePage.js @@ -1,8 +1,8 @@ import React from 'react'; import {Col} from 'react-bootstrap'; import rainge from 'rainge'; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {faCopyright} from "@fortawesome/free-regular-svg-icons"; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faCopyright} from '@fortawesome/free-regular-svg-icons'; class LicensePageComponent extends React.Component { constructor(props) { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js b/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js index f617036a6..df8aa08d0 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/LoginPage.js @@ -2,9 +2,9 @@ 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 Particles from 'react-particles-js'; +import {particleParams} from '../../styles/components/particle-component/AuthPageParams'; +import monkeyGeneral from '../../images/militant-monkey.svg'; class LoginPageComponent extends React.Component { login = (event) => { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js index 9ca26ae22..ae14b6a47 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/MapPage.js @@ -9,7 +9,7 @@ import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph'; import {getOptions, edgeGroupToColor} from 'components/map/MapOptions'; import AuthComponent from '../AuthComponent'; import '../../styles/components/Map.scss'; -import {faInfoCircle} from "@fortawesome/free-solid-svg-icons/faInfoCircle"; +import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; class MapPageComponent extends AuthComponent { constructor(props) { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js index 155dca40b..a75a65f24 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js @@ -8,8 +8,8 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faClipboard} from '@fortawesome/free-solid-svg-icons/faClipboard'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faSync} from '@fortawesome/free-solid-svg-icons/faSync'; -import {faInfoCircle} from "@fortawesome/free-solid-svg-icons/faInfoCircle"; -import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons/faExclamationTriangle"; +import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; +import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'; import {Link} from 'react-router-dom'; import AuthComponent from '../AuthComponent'; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js b/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js index 5c665bd0e..c536146bf 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/StartOverPage.js @@ -5,8 +5,8 @@ import AuthComponent from '../AuthComponent'; import StartOverModal from '../ui-components/StartOverModal'; import '../../styles/pages/StartOverPage.scss'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {faInfoCircle} from "@fortawesome/free-solid-svg-icons/faInfoCircle"; -import {faCheck} from "@fortawesome/free-solid-svg-icons/faCheck"; +import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; +import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; class StartOverPageComponent extends AuthComponent { constructor(props) { diff --git a/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js b/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js index 2d75272a3..9c0355aa2 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/TelemetryPage.js @@ -7,7 +7,7 @@ import download from 'downloadjs'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import '../../styles/pages/TelemetryPage.scss'; -import {faDownload} from "@fortawesome/free-solid-svg-icons/faDownload"; +import {faDownload} from '@fortawesome/free-solid-svg-icons/faDownload'; const renderJson = (val) => ; const renderTime = (val) => val.split('.')[0]; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js index 3372d1d33..5ab7e4f6e 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/AttackReport.js @@ -48,7 +48,7 @@ class AttackReport extends React.Component { } } - onTechniqueSelect = (technique, value) => { + onTechniqueSelect = (technique, _) => { let selectedTechnique = this.getTechniqueByTitle(technique); if (selectedTechnique === false){ return; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js index e0d433537..067069fab 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/SecurityReport.js @@ -473,7 +473,7 @@ class ReportPageComponent extends AuthComponent { } generateShellshockPathListBadges(paths) { - return paths.map(path => {path}); + return paths.map(path => {path}); } generateSmbPasswordIssue(issue) { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/MonkeysStillAliveWarning.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/MonkeysStillAliveWarning.js index 55a426ee5..19c2198cc 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/common/MonkeysStillAliveWarning.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/MonkeysStillAliveWarning.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import * as PropTypes from 'prop-types'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons/faExclamationTriangle"; +import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'; export default class MonkeysStillAliveWarning extends Component { render() { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/MustRunMonkeyWarning.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/MustRunMonkeyWarning.js index 1d90bab2f..2df46d5be 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/common/MustRunMonkeyWarning.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/MustRunMonkeyWarning.js @@ -1,7 +1,7 @@ import React, {Component} from 'react'; import {NavLink} from 'react-router-dom'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons/faExclamationTriangle"; +import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'; export default class MustRunMonkeyWarning extends Component { render() { diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/PrintReportButton.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/PrintReportButton.js index e0ae0ed3d..b5589997a 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/common/PrintReportButton.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/PrintReportButton.js @@ -7,7 +7,7 @@ import { faPrint } from '@fortawesome/free-solid-svg-icons/faPrint'; export default class PrintReportButton extends Component { render() { return
    -
    diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js index 936a2825b..7bbef33bc 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/common/RenderArrays.js @@ -1,4 +1,4 @@ -import React from "react"; +import React from 'react'; export let renderArray = function (val) { return <>{val.map(x =>
    {x}
    )}; diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js index 1a4b02efe..827549c1a 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/BreachedServers.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; -import {renderArray, renderIpAddresses} from "../common/RenderArrays"; +import {renderArray, renderIpAddresses} from '../common/RenderArrays'; const columns = [ diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js index cc9ea1c20..390ad6189 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/PostBreach.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; -import {renderIpAddresses} from "../common/RenderArrays"; +import {renderIpAddresses} from '../common/RenderArrays'; let renderMachine = function (data) { return
    {data.label} ( {renderIpAddresses(data)} )
    @@ -56,7 +56,7 @@ class PostBreachComponent extends React.Component { }); let defaultPageSize = pbaMachines.length > pageSize ? pageSize : pbaMachines.length; let showPagination = pbaMachines > pageSize; - const pbaCount = pbaMachines.reduce((accumulated, pbaMachine) => accumulated+pbaMachine["pba_results"].length, 0); + const pbaCount = pbaMachines.reduce((accumulated, pbaMachine) => accumulated+pbaMachine['pba_results'].length, 0); return ( <>

    diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js index bf0eee7d6..229bbfed2 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/ScannedServers.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactTable from 'react-table'; import Pluralize from 'pluralize'; -import {renderArray, renderIpAddresses} from "../common/RenderArrays"; +import {renderArray, renderIpAddresses} from '../common/RenderArrays'; const columns = [ @@ -32,7 +32,7 @@ class ScannedServersComponent extends React.Component { let showPagination = this.props.data.length > pageSize; const scannedMachinesCount = this.props.data.length; - const reducerFromScannedServerToServicesAmount = (accumulated, scannedServer) => accumulated + scannedServer["services"].length; + const reducerFromScannedServerToServicesAmount = (accumulated, scannedServer) => accumulated + scannedServer['services'].length; const scannedServicesAmount = this.props.data.reduce(reducerFromScannedServerToServicesAmount, 0); return ( diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js b/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js index 013426657..678cf0305 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/security/StrongUsers.js @@ -1,6 +1,6 @@ import React from 'react'; import ReactTable from 'react-table' -import {renderArray} from "../common/RenderArrays"; +import {renderArray} from '../common/RenderArrays'; const columns = [ diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js index f83921dae..5c99b4866 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/FindingsTable.js @@ -18,11 +18,13 @@ const columns = [ { Header: 'Events', id: 'events', accessor: x => { - return ; + comp.displayName = 'EventsButton_' + x.finding_id; + return comp; }, maxWidth: EVENTS_COLUMN_MAX_WIDTH }, @@ -34,7 +36,9 @@ const columns = [ const pillarLabels = pillars.map((pillar) => ); - return

    {pillarLabels}
    ; + const comp =
    {pillarLabels}
    ; + comp.displayName = 'PillarsLabels'; + return comp; }, maxWidth: PILLARS_COLUMN_MAX_WIDTH, style: {'whiteSpace': 'unset'} diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PrinciplesStatusTable.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PrinciplesStatusTable.js index 6b1d22f6f..6771747e0 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PrinciplesStatusTable.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/PrinciplesStatusTable.js @@ -13,7 +13,9 @@ const columns = [ { Header: 'Status', id: 'status', accessor: x => { - return ; + const comp = ; + comp.displayName = 'StatusLabel'; + return comp; }, maxWidth: MAX_WIDTH_STATUS_COLUMN }, @@ -25,7 +27,9 @@ const columns = [ Header: 'Monkey Tests', id: 'tests', style: {'whiteSpace': 'unset'}, // This enables word wrap accessor: x => { - return ; + const comp = ; + comp.displayName = 'TestsStatus'; + return comp; } } ] diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ReportLegend.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ReportLegend.js index 02e156439..e3c94981a 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ReportLegend.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/ReportLegend.js @@ -14,7 +14,7 @@ class ZeroTrustReportLegend extends Component { super(props, context); this.state = { - open: false, + open: false }; } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js index feff49e2a..12eac609f 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/SinglePillarPrinciplesStatus.js @@ -15,7 +15,7 @@ export default class SinglePillarPrinciplesStatus extends AuthComponent { super(props, context); this.state = { - open: false, + open: false }; } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js index a7fc698a0..e6a2ddd36 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/venn-components/VennDiagram.js @@ -149,7 +149,7 @@ class VennDiagram extends React.Component { } else { // Return z indices to default - Object.keys(this.layout).forEach(function (d_, i_) { + Object.keys(this.layout).forEach(function (_d, i_) { document.querySelector('#' + self.prefix).appendChild(document.querySelector('#' + self.prefix + 'Node_' + i_).parentNode); }) } diff --git a/monkey/monkey_island/cc/ui/src/components/run-monkey/AwsRunTable.js b/monkey/monkey_island/cc/ui/src/components/run-monkey/AwsRunTable.js index ac9231d82..cbf209a2d 100644 --- a/monkey/monkey_island/cc/ui/src/components/run-monkey/AwsRunTable.js +++ b/monkey/monkey_island/cc/ui/src/components/run-monkey/AwsRunTable.js @@ -67,7 +67,7 @@ class AwsRunTableComponent extends React.Component { this.setState({selectAll, selection}); }; - getTrProps = (s, r) => { + getTrProps = (_, r) => { let color = 'inherit'; if (r) { let instId = r.original.instance_id; diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js b/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js index cd3315428..5c963d87e 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/InfoPane.js @@ -1,7 +1,7 @@ import {Card, Button} from 'react-bootstrap'; import React from 'react'; -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {faQuestionCircle} from "@fortawesome/free-solid-svg-icons"; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons'; function InfoPane(props) { diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/MissingBinariesModal.js b/monkey/monkey_island/cc/ui/src/components/ui-components/MissingBinariesModal.js index c73094fb6..ae7f6ac4e 100644 --- a/monkey/monkey_island/cc/ui/src/components/ui-components/MissingBinariesModal.js +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/MissingBinariesModal.js @@ -1,6 +1,5 @@ import {Modal} from 'react-bootstrap'; import React from 'react'; -import {GridLoader} from 'react-spinners'; class MissingBinariesModal extends React.PureComponent { From 02a710e15a1fa96cb5c49c93bd64c7ee61bbc523 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 27 Jul 2020 11:49:31 +0300 Subject: [PATCH 36/40] Updated default password list according to the most popular password statistics --- monkey/monkey_island/cc/services/config_schema/basic.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/monkey/monkey_island/cc/services/config_schema/basic.py b/monkey/monkey_island/cc/services/config_schema/basic.py index b141db010..06d2eda7c 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic.py +++ b/monkey/monkey_island/cc/services/config_schema/basic.py @@ -58,10 +58,13 @@ BASIC = { "type": "string" }, "default": [ - "Password1!", - "1234", + "root", + "123456", "password", - "12345678" + "123456789", + "qwerty", + "111111", + "iloveyou" ], "description": "List of passwords that will be used by exploiters that need credentials, like " "SSH brute-forcing." From 026daba3e0b1815e46f3d4825f02b9a2dfdee0db Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 27 Jul 2020 11:57:40 +0300 Subject: [PATCH 37/40] Validation bugfix (unescaped .), improved comments --- .../configuration-components/ValidationFormats.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js index db2bcb29c..eb9c5ecc9 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js @@ -1,4 +1,4 @@ -const ipRegex = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' +const ipRegex = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' const cidrNotationRegex = '([0-9]|1[0-9]|2[0-9]|3[0-2])' const hostnameRegex = '^([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*)$' @@ -9,10 +9,10 @@ export const formValidationFormats = { function buildIpRangeRegex(){ return new RegExp([ - '^'+ipRegex+'$|', // Single IP - '^'+ipRegex+'-'+ipRegex+'$|', // IP range IP-IP + '^'+ipRegex+'$|', // Single: IP + '^'+ipRegex+'-'+ipRegex+'$|', // IP range: IP-IP '^'+ipRegex+'/'+cidrNotationRegex+'$|', // IP range with cidr notation: IP/cidr - hostnameRegex, // IP range with cidr notation: IP/cidr + hostnameRegex, // Hostname: target.tg ].join('')) } From 0be9b19186eb461ae43dc762805eff8d811893a1 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 27 Jul 2020 15:31:25 +0300 Subject: [PATCH 38/40] Added custom config validation errors --- .../ValidationErrorMessages.js | 14 ++++++++++++++ .../configuration-components/ValidationFormats.js | 8 ++++++-- .../cc/ui/src/components/pages/ConfigurePage.js | 14 +++++++------- 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationErrorMessages.js diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationErrorMessages.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationErrorMessages.js new file mode 100644 index 000000000..3d20998ab --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationErrorMessages.js @@ -0,0 +1,14 @@ +import {IP, IP_RANGE} from "./ValidationFormats"; + +export default function transformErrors(errors) { + return errors.map(error => { + if (error.name === "type") { + error.message = "Field can't be empty." + } else if (error.name === "format" && error.params.format === IP_RANGE) { + error.message = "Invalid IP range, refer to description for valid examples." + } else if (error.name === "format" && error.params.format === IP) { + error.message = "Invalid IP." + } + return error; + }); +} diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js index eb9c5ecc9..18705660d 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ValidationFormats.js @@ -2,12 +2,16 @@ const ipRegex = '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0 const cidrNotationRegex = '([0-9]|1[0-9]|2[0-9]|3[0-2])' const hostnameRegex = '^([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*.?)*([A-Za-z0-9]*[A-Za-z]+[A-Za-z0-9]*)$' +export const IP_RANGE = 'ip-range'; +export const IP = 'ip'; + export const formValidationFormats = { - 'ip-range': buildIpRangeRegex(), - 'ip': buildIpRegex(), + [IP_RANGE]: buildIpRangeRegex(), + [IP]: buildIpRegex() }; function buildIpRangeRegex(){ + console.log(formValidationFormats); return new RegExp([ '^'+ipRegex+'$|', // Single: IP '^'+ipRegex+'-'+ipRegex+'$|', // IP range: IP-IP diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index e7ef099e5..dd38a3cf0 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -10,6 +10,7 @@ import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; import {formValidationFormats} from '../configuration-components/ValidationFormats'; +import transformErrors from '../configuration-components/ValidationErrorMessages'; import InternalConfig from '../configuration-components/InternalConfig'; const ATTACK_URL = '/api/attack'; @@ -258,8 +259,6 @@ class ConfigurePageComponent extends AuthComponent { this.setState({attackConfig: res.configuration}); this.setInitialAttackConfig(res.configuration); }) - - }; removePBAfile(apiEndpoint, setFilenameFnc) { @@ -341,11 +340,12 @@ class ConfigurePageComponent extends AuthComponent { setPbaFilenameLinux: this.setPbaFilenameLinux, selectedSection: this.state.selectedSection }) - formProperties['formData'] = this.state.configuration[this.state.selectedSection] - formProperties['onChange'] = this.onChange - formProperties['customFormats'] = formValidationFormats - formProperties['className'] = 'config-form' - formProperties['liveValidate'] = true + formProperties['formData'] = this.state.configuration[this.state.selectedSection]; + formProperties['onChange'] = this.onChange; + formProperties['customFormats'] = formValidationFormats; + formProperties['transformErrors'] = transformErrors; + formProperties['className'] = 'config-form'; + formProperties['liveValidate'] = true; if (this.state.selectedSection === 'internal') { return () From 64a8d714395cd93ebc2bd7e04678df96d1d4a15e Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 27 Jul 2020 16:48:33 +0300 Subject: [PATCH 39/40] Added the the ability to assing info/warnings to configuration fields/sections. Moved network warning under "Scope" --- .../services/config_schema/basic_network.py | 4 +++- .../configuration-components/FieldWithInfo.js | 20 +++++++++++++++++++ .../configuration-components/UiSchema.js | 6 +++++- .../ui/src/components/pages/ConfigurePage.js | 14 ------------- 4 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 monkey/monkey_island/cc/ui/src/components/configuration-components/FieldWithInfo.js diff --git a/monkey/monkey_island/cc/services/config_schema/basic_network.py b/monkey/monkey_island/cc/services/config_schema/basic_network.py index 0fd3344e8..33467690a 100644 --- a/monkey/monkey_island/cc/services/config_schema/basic_network.py +++ b/monkey/monkey_island/cc/services/config_schema/basic_network.py @@ -19,7 +19,9 @@ BASIC_NETWORK = { }, "default": [ ], - "description": "List of IPs that the Monkey will not scan." + "description": "List of IPs that the Monkey will not scan.", + "info": "The Monkey scans its subnet if \"Local network scan\" is ticked. " + "Additionally the monkey scans machines according to \"Scan target list\"." }, "local_network_scan": { "title": "Local network scan", diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/FieldWithInfo.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/FieldWithInfo.js new file mode 100644 index 000000000..8a0bc0c04 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/FieldWithInfo.js @@ -0,0 +1,20 @@ +import ObjectField from 'react-jsonschema-form-bs4/lib/components/fields/ArrayField'; +import * as React from 'react'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; + +class FieldWithInfo extends React.Component { + + render() { + return ( + <> +
    + + {this.props.schema.info} +
    + + ); + } +} + +export default FieldWithInfo; diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js index 914d23ed3..aab3f1899 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/UiSchema.js @@ -1,6 +1,7 @@ import AdvancedMultiSelect from '../ui-components/AdvancedMultiSelect'; import PbaInput from './PbaInput'; import {API_PBA_LINUX, API_PBA_WINDOWS} from '../pages/ConfigurePage'; +import FieldWithInfo from './FieldWithInfo'; export default function UiSchema(props) { const UiSchema = { @@ -16,7 +17,10 @@ export default function UiSchema(props) { basic_network: { 'ui:order': ['scope', 'network_analysis'], scope: { - subnet_scan_list:{ + blocked_ips: { + 'ui:field': FieldWithInfo + }, + subnet_scan_list: { format: 'ip-list' } } diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index dd38a3cf0..7da7ca14c 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -6,7 +6,6 @@ import AuthComponent from '../AuthComponent'; import ConfigMatrixComponent from '../attack/ConfigMatrixComponent'; import UiSchema from '../configuration-components/UiSchema'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; -import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'; import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamationCircle'; import {formValidationFormats} from '../configuration-components/ValidationFormats'; @@ -352,7 +351,6 @@ class ConfigurePageComponent extends AuthComponent { } else { return (
    - {this.renderBasicNetworkWarning()}
    @@ -377,18 +375,6 @@ class ConfigurePageComponent extends AuthComponent { }) } - renderBasicNetworkWarning = () => { - if (this.state.selectedSection === 'basic_network') { - return (
    - - The Monkey scans its subnet if "Local network scan" is ticked. Additionally the monkey scans machines - according to "Scan target list". -
    ) - } else { - return (
    ) - } - }; - renderNav = () => { return (