diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index a03e6a512..32e6c3a39 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -3,7 +3,7 @@ import logging from monkey_island.cc.models import Monkey from monkey_island.cc.services.attack.technique_reports import T1210, T1197, T1110, T1075, T1003, T1059, T1086, T1082 from monkey_island.cc.services.attack.technique_reports import T1145, T1105, T1065, T1035, T1129, T1106, T1107, T1188 -from monkey_island.cc.services.attack.technique_reports import T1090, T1041, T1222, T1005, T1018, T1016 +from monkey_island.cc.services.attack.technique_reports import T1090, T1041, T1222, T1005, T1018, T1016, T1021 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -33,7 +33,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1222': T1222.T1222, 'T1005': T1005.T1005, 'T1018': T1018.T1018, - 'T1016': T1016.T1016} + 'T1016': T1016.T1016, + 'T1021': T1021.T1021} 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 9d396dc26..2335f005c 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -48,6 +48,15 @@ SCHEMA = { "necessary": True, "description": "Files may be copied from one system to another to stage " "adversary tools or other files over the course of an operation." + }, + "T1021": { + "title": "T1021 Remote services", + "type": "bool", + "value": True, + "necessary": False, + "depends_on": ["T1110"], + "description": "An adversary may use Valid Accounts to log into a service" + " specifically designed to accept remote connections." } } }, @@ -62,7 +71,7 @@ SCHEMA = { "necessary": False, "description": "Adversaries may use brute force techniques to attempt access to accounts " "when passwords are unknown or when password hashes are obtained.", - "depends_on": ["T1210"] + "depends_on": ["T1210", "T1021"] }, "T1003": { "title": "T1003 Credential dumping", diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1021.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1021.py new file mode 100644 index 000000000..6f69f39ab --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1021.py @@ -0,0 +1,54 @@ +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique +from common.utils.attack_utils import ScanStatus +from monkey_island.cc.services.attack.technique_reports.T1110 import T1110 + +__author__ = "VakarisZ" + + +class T1021(AttackTechnique): + tech_id = "T1021" + unscanned_msg = "Monkey didn't try to login to any remote services." + scanned_msg = "Monkey tried to login to remote services with valid credentials, but failed." + used_msg = "Monkey successfully logged into remote services on the network." + + # Gets data about brute force attempts + query = [{'$match': {'telem_category': 'exploit', + 'data.attempts': {'$not': {'$size': 0}}}}, + {'$project': {'_id': 0, + 'machine': '$data.machine', + 'info': '$data.info', + 'attempt_cnt': {'$size': '$data.attempts'}, + 'attempts': {'$filter': {'input': '$data.attempts', + 'as': 'attempt', + 'cond': {'$and': [{'$eq': ['$$attempt.result', True]}, + {'$or': [{'$ne': ['$$attempt.password', '']}, + {'$ne': ['$$attempt.ssh_key', '']}]}] + } + } + } + } + }] + + scanned_query = {'telem_category': 'exploit', + 'data.attempts': {'$elemMatch': {'$or': [{'password': {'$ne': ''}}, + {'ssh_key': {'$ne': ''}}]}}} + + @staticmethod + def get_report_data(): + attempts = [] + if mongo.db.telemetry.count_documents(T1021.scanned_query): + attempts = list(mongo.db.telemetry.aggregate(T1021.query)) + if attempts: + status = ScanStatus.USED.value + for result in attempts: + result['successful_creds'] = [] + for attempt in result['attempts']: + result['successful_creds'].append(T1110.parse_creds(attempt)) + else: + status = ScanStatus.SCANNED.value + else: + status = ScanStatus.UNSCANNED.value + data = T1021.get_base_data_by_status(status) + data.update({'services': attempts}) + return data diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1021.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1021.js new file mode 100644 index 000000000..edfba66a9 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1021.js @@ -0,0 +1,44 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { renderMachine, scanStatus } from "./Helpers" + + +class T1021 extends React.Component { + + constructor(props) { + super(props); + } + + static getServiceColumns() { + return ([{ + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => renderMachine(x.machine), + style: { 'whiteSpace': 'unset' }, width: 160}, + {Header: 'Service', id: 'service', accessor: x => x.info.display_name, style: { 'whiteSpace': 'unset' }, width: 100}, + {Header: 'Valid account used', id: 'credentials', accessor: x => this.renderCreds(x.successful_creds), style: { 'whiteSpace': 'unset' }}, + ] + }])}; + + static renderCreds(creds) { + return {creds.map(cred =>
{cred}
)}
+ }; + + render() { + return ( +
+
{this.props.data.message}
+
+ {this.props.data.status === scanStatus.USED ? + : ""} +
+ ); + } +} + +export default T1021; 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 3d565c3a0..86fce36e5 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 @@ -28,6 +28,7 @@ import T1222 from "../attack/techniques/T1222"; import T1005 from "../attack/techniques/T1005"; import T1018 from "../attack/techniques/T1018"; import T1016 from "../attack/techniques/T1016"; +import T1021 from "../attack/techniques/T1021"; const tech_components = { 'T1210': T1210, @@ -51,7 +52,8 @@ const tech_components = { 'T1222': T1222, 'T1005': T1005, 'T1018': T1018, - 'T1016': T1016 + 'T1016': T1016, + 'T1021': T1021 }; const classNames = require('classnames');