diff --git a/monkey/common/data/post_breach_consts.py b/monkey/common/data/post_breach_consts.py index c3bba9950..2b8b808a1 100644 --- a/monkey/common/data/post_breach_consts.py +++ b/monkey/common/data/post_breach_consts.py @@ -6,3 +6,4 @@ POST_BREACH_HIDDEN_FILES = "Hide files and directories" POST_BREACH_TRAP_COMMAND = "Execute command when a particular signal is received" POST_BREACH_SETUID_SETGID = "Setuid and Setgid" POST_BREACH_JOB_SCHEDULING = "Schedule jobs" +POST_BREACH_ACCOUNT_DISCOVERY = "Account discovery" diff --git a/monkey/infection_monkey/post_breach/account_discovery/account_discovery.py b/monkey/infection_monkey/post_breach/account_discovery/account_discovery.py new file mode 100644 index 000000000..952592ace --- /dev/null +++ b/monkey/infection_monkey/post_breach/account_discovery/account_discovery.py @@ -0,0 +1,10 @@ +from infection_monkey.post_breach.account_discovery.linux_account_discovery import \ + get_linux_commands_to_discover_accounts +from infection_monkey.post_breach.account_discovery.windows_account_discovery import \ + get_windows_commands_to_discover_accounts + + +def get_commands_to_discover_accounts(): + linux_cmds = get_linux_commands_to_discover_accounts() + windows_cmds = get_windows_commands_to_discover_accounts() + return linux_cmds, windows_cmds diff --git a/monkey/infection_monkey/post_breach/account_discovery/linux_account_discovery.py b/monkey/infection_monkey/post_breach/account_discovery/linux_account_discovery.py new file mode 100644 index 000000000..21725e509 --- /dev/null +++ b/monkey/infection_monkey/post_breach/account_discovery/linux_account_discovery.py @@ -0,0 +1,7 @@ +def get_linux_commands_to_discover_accounts(): + return [ + "echo \'Discovered the following user accounts:\'; ", + "cut -d: -f1,3 /etc/passwd | ", + "egrep ':[0-9]{4}$' | ", + "cut -d: -f1" + ] diff --git a/monkey/infection_monkey/post_breach/account_discovery/windows_account_discovery.py b/monkey/infection_monkey/post_breach/account_discovery/windows_account_discovery.py new file mode 100644 index 000000000..325f7ad43 --- /dev/null +++ b/monkey/infection_monkey/post_breach/account_discovery/windows_account_discovery.py @@ -0,0 +1,4 @@ +def get_windows_commands_to_discover_accounts(): + return [ + "net user" + ] diff --git a/monkey/infection_monkey/post_breach/actions/discover_accounts.py b/monkey/infection_monkey/post_breach/actions/discover_accounts.py new file mode 100644 index 000000000..f934762e6 --- /dev/null +++ b/monkey/infection_monkey/post_breach/actions/discover_accounts.py @@ -0,0 +1,12 @@ +from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY +from infection_monkey.post_breach.pba import PBA +from infection_monkey.post_breach.account_discovery.account_discovery import \ + get_commands_to_discover_accounts + + +class AccountDiscovery(PBA): + def __init__(self): + linux_cmds, windows_cmds = get_commands_to_discover_accounts() + super().__init__(POST_BREACH_ACCOUNT_DISCOVERY, + linux_cmd=' '.join(linux_cmds), + windows_cmd=' '.join(windows_cmds)) diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index 6d4bac9ed..5e02c1fee 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -18,7 +18,8 @@ from monkey_island.cc.services.attack.technique_reports import (T1003, T1005, T1158, T1166, T1168, T1188, T1197, T1210, - T1222, T1504) + T1222, T1504, + T1087) from monkey_island.cc.services.reporting.report_generation_synchronisation import \ safe_generate_attack_report @@ -57,7 +58,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1154': T1154.T1154, 'T1166': T1166.T1166, 'T1168': T1168.T1168, - 'T1053': T1053.T1053 + 'T1053': T1053.T1053, + 'T1087': T1087.T1087 } REPORT_NAME = 'new_report' diff --git a/monkey/monkey_island/cc/services/attack/attack_schema.py b/monkey/monkey_island/cc/services/attack/attack_schema.py index 30d33ca3e..3e96e4cf8 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -234,6 +234,16 @@ SCHEMA = { "type": "object", "link": "https://attack.mitre.org/tactics/TA0007/", "properties": { + "T1087": { + "title": "Account Discovery", + "type": "bool", + "value": True, + "necessary": False, + "link": "https://attack.mitre.org/techniques/T1087", + "description": "Adversaries may attempt to get a listing of accounts on a system or " + "within an environment. This information can help adversaries determine which " + "accounts exist to aid in follow-on behavior." + }, "T1018": { "title": "Remote System Discovery", "type": "bool", diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py new file mode 100644 index 000000000..de0a6a470 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1087.py @@ -0,0 +1,13 @@ +from common.data.post_breach_consts import POST_BREACH_ACCOUNT_DISCOVERY +from monkey_island.cc.services.attack.technique_reports.pba_technique import \ + PostBreachTechnique + +__author__ = "shreyamalviya" + + +class T1087(PostBreachTechnique): + tech_id = "T1087" + unscanned_msg = "Monkey didn't try to get a listing of user accounts." + scanned_msg = "Monkey tried to get a listing of user accounts but failed to do so." + used_msg = "Monkey got a listing of user accounts successfully." + pba_names = [POST_BREACH_ACCOUNT_DISCOVERY] 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 f3e2a9bfa..7e36a1bb2 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 @@ -70,6 +70,15 @@ POST_BREACH_ACTIONS = { "title": "Job scheduling", "info": "Attempts to create a scheduled job on the system and remove it.", "attack_techniques": ["T1168", "T1053"] + }, + { + "type": "string", + "enum": [ + "AccountDiscovery" + ], + "title": "Account Discovery", + "info": "Attempts to get a listing of user accounts on the system.", + "attack_techniques": ["T1087"] } ] } diff --git a/monkey/monkey_island/cc/services/config_schema/monkey.py b/monkey/monkey_island/cc/services/config_schema/monkey.py index dd10cb35b..c9fbdde74 100644 --- a/monkey/monkey_island/cc/services/config_schema/monkey.py +++ b/monkey/monkey_island/cc/services/config_schema/monkey.py @@ -67,7 +67,8 @@ MONKEY = { "HiddenFiles", "TrapCommand", "ChangeSetuidSetgid", - "ScheduleJobs" + "ScheduleJobs", + "AccountDiscovery" ] }, } diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1087.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1087.js new file mode 100644 index 000000000..1973580d3 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1087.js @@ -0,0 +1,45 @@ +import React from 'react'; +import ReactTable from 'react-table'; +import {renderMachineFromSystemData, ScanStatus} from './Helpers'; +import MitigationsComponent from './MitigationsComponent'; + +class T1087 extends React.Component { + + constructor(props) { + super(props); + } + + static getColumns() { + return ([{ + columns: [ + { Header: 'Machine', + id: 'machine', + accessor: x => renderMachineFromSystemData(x.machine), + style: {'whiteSpace': 'unset'}}, + { Header: 'Result', + id: 'result', + accessor: x => x.result, + style: {'whiteSpace': 'unset'}} + ] + }]) + } + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.status === ScanStatus.USED ? + : ''} + +
+ ); + } + } + + export default T1087;