diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py index 5d3ea8f8c..4e81811d0 100644 --- a/monkey/infection_monkey/exploit/shellshock.py +++ b/monkey/infection_monkey/exploit/shellshock.py @@ -6,11 +6,13 @@ from random import choice import requests +from common.utils.attack_utils import ScanStatus from infection_monkey.exploit import HostExploiter from infection_monkey.exploit.tools.helpers import get_target_monkey, get_monkey_depth, build_monkey_commandline from infection_monkey.model import DROPPER_ARG from infection_monkey.exploit.shellshock_resources import CGI_FILES from infection_monkey.exploit.tools.http_tools import HTTPTools +from infection_monkey.telemetry.attack.t1222_telem import T1222Telem __author__ = 'danielg' @@ -131,6 +133,7 @@ class ShellShockExploiter(HostExploiter): chmod = '/bin/chmod +x %s' % dropper_target_path_linux run_path = exploit + chmod self.attack_page(url, header, run_path) + T1222Telem(ScanStatus.USED, chmod).send() # run the monkey cmdline = "%s %s" % (dropper_target_path_linux, DROPPER_ARG) diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index dfa922b24..eed36a30d 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -13,6 +13,7 @@ from infection_monkey.network.tools import check_tcp_port from common.utils.exploit_enum import ExploitType from common.utils.attack_utils import ScanStatus from infection_monkey.telemetry.attack.t1105_telem import T1105Telem +from infection_monkey.telemetry.attack.t1222_telem import T1222Telem __author__ = 'hoffer' @@ -164,6 +165,7 @@ class SSHExploiter(HostExploiter): ftp.putfo(file_obj, self._config.dropper_target_path_linux, file_size=monkeyfs.getsize(src_path), callback=self.log_transfer) ftp.chmod(self._config.dropper_target_path_linux, 0o777) + T1222Telem(ScanStatus.USED, "chmod 0777 %s" % self._config.dropper_target_path_linux).send() T1105Telem(ScanStatus.USED, get_interface_to_target(self.host.ip_addr), self.host.ip_addr, diff --git a/monkey/infection_monkey/exploit/vsftpd.py b/monkey/infection_monkey/exploit/vsftpd.py index adac06f2d..dd7e5080c 100644 --- a/monkey/infection_monkey/exploit/vsftpd.py +++ b/monkey/infection_monkey/exploit/vsftpd.py @@ -6,12 +6,16 @@ import socket import time + +from common.utils.attack_utils import ScanStatus from infection_monkey.exploit import HostExploiter from infection_monkey.exploit.tools.helpers import get_target_monkey, build_monkey_commandline, get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.model import MONKEY_ARG, CHMOD_MONKEY, RUN_MONKEY, WGET_HTTP_UPLOAD, DOWNLOAD_TIMEOUT from logging import getLogger +from infection_monkey.telemetry.attack.t1222_telem import T1222Telem + LOG = getLogger(__name__) __author__ = 'D3fa1t' @@ -125,6 +129,7 @@ class VSFTPDExploiter(HostExploiter): change_permission = str.encode(str(change_permission) + '\n') LOG.info("change_permission command is %s", change_permission) backdoor_socket.send(change_permission) + T1222Telem(ScanStatus.USED, change_permission).send() # Run monkey on the machine parameters = build_monkey_commandline(self.host, get_monkey_depth() - 1) diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index b33a3cfb5..35bcb2f9b 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -10,6 +10,7 @@ from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.network.tools import check_tcp_port, tcp_port_to_service from infection_monkey.telemetry.attack.t1197_telem import T1197Telem from common.utils.attack_utils import ScanStatus, BITS_UPLOAD_STRING +from infection_monkey.telemetry.attack.t1222_telem import T1222Telem __author__ = 'VakarisZ' @@ -367,8 +368,10 @@ class WebRCE(HostExploiter): command = CHMOD_MONKEY % {'monkey_path': path} try: resp = self.exploit(url, command) + T1222Telem(ScanStatus.USED, command).send() except Exception as e: LOG.error("Something went wrong while trying to change permission: %s" % e) + T1222Telem(ScanStatus.SCANNED, "").send() return False # If exploiter returns True / False if type(resp) is bool: diff --git a/monkey/infection_monkey/telemetry/attack/t1222_telem.py b/monkey/infection_monkey/telemetry/attack/t1222_telem.py new file mode 100644 index 000000000..a9541a2ec --- /dev/null +++ b/monkey/infection_monkey/telemetry/attack/t1222_telem.py @@ -0,0 +1,19 @@ +from infection_monkey.telemetry.attack.attack_telem import AttackTelem + + +class T1222Telem(AttackTelem): + def __init__(self, status, command): + """ + T1222 telemetry. + :param status: ScanStatus of technique + :param command: command used to change permissions + """ + super(T1222Telem, self).__init__('T1222', status) + self.command = command + + def get_data(self): + data = super(T1222Telem, self).get_data() + data.update({ + 'command': self.command + }) + return data diff --git a/monkey/monkey_island/cc/services/attack/attack_report.py b/monkey/monkey_island/cc/services/attack/attack_report.py index ae6ee78e0..fab00c213 100644 --- a/monkey/monkey_island/cc/services/attack/attack_report.py +++ b/monkey/monkey_island/cc/services/attack/attack_report.py @@ -1,8 +1,9 @@ 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 +from monkey_island.cc.services.attack.technique_reports import T1090, T1041, T1222 from monkey_island.cc.services.attack.attack_config import AttackConfig from monkey_island.cc.database import mongo @@ -28,7 +29,8 @@ TECHNIQUES = {'T1210': T1210.T1210, 'T1107': T1107.T1107, 'T1188': T1188.T1188, 'T1090': T1090.T1090, - 'T1041': T1041.T1041} + 'T1041': T1041.T1041, + 'T1222': T1222.T1222} 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 c7c76b998..caa058df4 100644 --- a/monkey/monkey_island/cc/services/attack/attack_schema.py +++ b/monkey/monkey_island/cc/services/attack/attack_schema.py @@ -108,6 +108,13 @@ SCHEMA = { "description": "Adversaries may remove files over the course of an intrusion " "to keep their footprint low or remove them at the end as part " "of the post-intrusion cleanup process." + }, + "T1222": { + "title": "T1222 File permissions modification", + "type": "bool", + "value": True, + "necessary": True, + "description": "Adversaries may modify file permissions/attributes to evade intended DACLs." } } }, diff --git a/monkey/monkey_island/cc/services/attack/technique_reports/T1222.py b/monkey/monkey_island/cc/services/attack/technique_reports/T1222.py new file mode 100644 index 000000000..9db288597 --- /dev/null +++ b/monkey/monkey_island/cc/services/attack/technique_reports/T1222.py @@ -0,0 +1,34 @@ +from common.utils.attack_utils import ScanStatus +from monkey_island.cc.database import mongo +from monkey_island.cc.services.attack.technique_reports import AttackTechnique + +__author__ = "VakarisZ" + + +class T1222(AttackTechnique): + tech_id = "T1222" + unscanned_msg = "Monkey didn't try to change any file permissions." + scanned_msg = "Monkey tried to change file permissions, but failed." + used_msg = "Monkey successfully changed file permissions in network systems." + + query = [{'$match': {'telem_category': 'attack', + 'data.technique': 'T1222', + 'data.status': ScanStatus.USED.value}}, + {'$lookup': {'from': 'monkey', + 'localField': 'monkey_guid', + 'foreignField': 'guid', + 'as': 'monkey'}}, + {'$project': {'monkey': {'$arrayElemAt': ['$monkey', 0]}, + 'status': '$data.status', + 'command': '$data.command'}}, + {'$addFields': {'_id': 0, + 'machine': {'hostname': '$monkey.hostname', 'ips': '$monkey.ip_addresses'}, + 'monkey': 0}}, + {'$group': {'_id': {'machine': '$machine', 'status': '$status', 'command': '$command'}}}, + {"$replaceRoot": {"newRoot": "$_id"}}] + + @staticmethod + def get_report_data(): + data = T1222.get_tech_base_data() + data.update({'commands': list(mongo.db.telemetry.aggregate(T1222.query))}) + return data diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1222.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1222.js new file mode 100644 index 000000000..3f3902343 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1222.js @@ -0,0 +1,39 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; +import { renderMachineFromSystemData, scanStatus } from "./Helpers" + + +class T1222 extends React.Component { + + constructor(props) { + super(props); + } + + static getCommandColumns() { + return ([{ + Header: "Permission modification commands", + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => renderMachineFromSystemData(x.machine), style: { 'whiteSpace': 'unset' }}, + {Header: 'Command', id: 'command', accessor: x => x.command, style: { 'whiteSpace': 'unset' }}, + ] + }])}; + + render() { + return ( +