diff --git a/monkey/infection_monkey/exploit/elasticgroovy.py b/monkey/infection_monkey/exploit/elasticgroovy.py index b4d3b2be8..eb6a3615c 100644 --- a/monkey/infection_monkey/exploit/elasticgroovy.py +++ b/monkey/infection_monkey/exploit/elasticgroovy.py @@ -58,6 +58,8 @@ class ElasticGroovyExploiter(WebRCE): result = self.get_results(response) if not result: return False + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'url': url, 'service': 'Elastic search'}).send() return result[0] def upload_monkey(self, url, commands=None): diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 1db521acd..059ffb9da 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -13,6 +13,8 @@ import posixpath from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.exploit.tools import HTTPTools, build_monkey_commandline, get_monkey_depth from infection_monkey.model import MONKEY_ARG, ID_STRING, HADOOP_WINDOWS_COMMAND, HADOOP_LINUX_COMMAND +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus __author__ = 'VakarisZ' @@ -48,6 +50,8 @@ class HadoopExploiter(WebRCE): return False http_thread.join(self.DOWNLOAD_TIMEOUT) http_thread.stop() + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'url': self.vulnerable_urls[0], 'service': 'Hadoop'}).send() return True def exploit(self, url, command): diff --git a/monkey/infection_monkey/exploit/rdpgrinder.py b/monkey/infection_monkey/exploit/rdpgrinder.py index 3b81f7109..99d13aa6a 100644 --- a/monkey/infection_monkey/exploit/rdpgrinder.py +++ b/monkey/infection_monkey/exploit/rdpgrinder.py @@ -280,10 +280,12 @@ class RdpExploiter(HostExploiter): cmdline = build_monkey_commandline(self.host, get_monkey_depth() - 1) if self._config.rdp_use_vbs_download: + download_method = 'VBS' command = RDP_CMDLINE_HTTP_VBS % { 'monkey_path': self._config.dropper_target_path_win_32, 'http_path': http_path, 'parameters': cmdline} else: + download_method = 'BITS' command = RDP_CMDLINE_HTTP_BITS % { 'monkey_path': self._config.dropper_target_path_win_32, 'http_path': http_path, 'parameters': cmdline} @@ -314,7 +316,8 @@ class RdpExploiter(HostExploiter): client_factory.done_event.wait() if client_factory.success: - VictimHostTelem("T1197", ScanStatus.USED.value, self.host, BITS_UPLOAD_STRING) + if download_method == 'BITS': + VictimHostTelem("T1197", ScanStatus.USED.value, self.host, BITS_UPLOAD_STRING) exploited = True self.report_login_attempt(True, user, password) break diff --git a/monkey/infection_monkey/exploit/sambacry.py b/monkey/infection_monkey/exploit/sambacry.py index 2468a42bc..5bc93ff28 100644 --- a/monkey/infection_monkey/exploit/sambacry.py +++ b/monkey/infection_monkey/exploit/sambacry.py @@ -4,7 +4,6 @@ import posixpath import re import time from io import BytesIO -from os import path import impacket.smbconnection from impacket.nmb import NetBIOSError @@ -22,6 +21,8 @@ from infection_monkey.model import DROPPER_ARG from infection_monkey.network.smbfinger import SMB_SERVICE from infection_monkey.exploit.tools import build_monkey_commandline, get_target_monkey_by_os, get_monkey_depth from infection_monkey.pyinstaller_utils import get_binary_file_path +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus __author__ = 'itay.mizeretz' @@ -89,6 +90,8 @@ class SambaCryExploiter(HostExploiter): LOG.info( "Shares triggered successfully on host %s: %s" % ( self.host.ip_addr, str(successfully_triggered_shares))) + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'port': '139/445', 'service': 'Samba'}).send() return True else: LOG.info("No shares triggered successfully on host %s" % self.host.ip_addr) diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py index a98cbda50..feeb0ccf2 100644 --- a/monkey/infection_monkey/exploit/shellshock.py +++ b/monkey/infection_monkey/exploit/shellshock.py @@ -11,6 +11,8 @@ from infection_monkey.exploit.tools import get_target_monkey, HTTPTools, get_mon from infection_monkey.model import DROPPER_ARG from infection_monkey.exploit.shellshock_resources import CGI_FILES from infection_monkey.exploit.tools import build_monkey_commandline +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus __author__ = 'danielg' @@ -143,7 +145,8 @@ class ShellShockExploiter(HostExploiter): if not (self.check_remote_file_exists(url, header, exploit, self._config.monkey_log_path_linux)): LOG.info("Log file does not exist, monkey might not have run") continue - + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'url': url, 'service': 'Bash'}).send() return True return False diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index 579fd8f1f..8c1469831 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -10,6 +10,8 @@ from infection_monkey.network import SMBFinger from infection_monkey.network.tools import check_tcp_port from infection_monkey.exploit.tools import build_monkey_commandline from common.utils.exploit_enum import ExploitType +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus LOG = getLogger(__name__) @@ -68,6 +70,10 @@ class SmbExploiter(HostExploiter): LOG.debug("Successfully logged in %r using SMB (%s : %s : %s : %s)", self.host, user, password, lm_hash, ntlm_hash) self.report_login_attempt(True, user, password, lm_hash, ntlm_hash) + VictimHostTelem('T1210', ScanStatus.USED.value, self.host, + {'port': ("%s or %s" % (SmbExploiter.KNOWN_PROTOCOLS['139/SMB'][1], + SmbExploiter.KNOWN_PROTOCOLS['445/SMB'][1])), + 'service': 'SMB'}).send() exploited = True break else: @@ -137,4 +143,8 @@ class SmbExploiter(HostExploiter): LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", remote_full_path, self.host, cmdline) + VictimHostTelem('T1210', ScanStatus.USED.value, self.host, + {'port': ("%s or %s" % (SmbExploiter.KNOWN_PROTOCOLS['139/SMB'][1], + SmbExploiter.KNOWN_PROTOCOLS['445/SMB'][1])), + 'service': 'Elastic'}).send() return True diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index 8a58f18c6..8dcd56175 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -11,6 +11,8 @@ from infection_monkey.model import MONKEY_ARG from infection_monkey.network.tools import check_tcp_port from infection_monkey.exploit.tools import build_monkey_commandline from common.utils.exploit_enum import ExploitType +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus __author__ = 'hoffer' @@ -81,6 +83,8 @@ class SSHExploiter(HostExploiter): LOG.debug("Successfully logged in %r using SSH (%s : %s)", self.host, user, curpass) exploited = True + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'port': port, 'service': 'SSH'}).send() self.report_login_attempt(True, user, curpass) break diff --git a/monkey/infection_monkey/exploit/struts2.py b/monkey/infection_monkey/exploit/struts2.py index 18f3d3a7e..96e2d7da6 100644 --- a/monkey/infection_monkey/exploit/struts2.py +++ b/monkey/infection_monkey/exploit/struts2.py @@ -10,6 +10,8 @@ import re import logging from infection_monkey.exploit.web_rce import WebRCE +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus __author__ = "VakarisZ" @@ -91,4 +93,6 @@ class Struts2Exploiter(WebRCE): except httplib.IncompleteRead as e: page = e.partial + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'url': url, 'service': 'Struts2'}).send() return page diff --git a/monkey/infection_monkey/exploit/weblogic.py b/monkey/infection_monkey/exploit/weblogic.py index 6d0748426..4f06efec0 100644 --- a/monkey/infection_monkey/exploit/weblogic.py +++ b/monkey/infection_monkey/exploit/weblogic.py @@ -10,6 +10,8 @@ from requests import post, exceptions from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.exploit.tools import get_free_tcp_port, get_interface_to_target from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus import threading import logging @@ -67,6 +69,9 @@ class WebLogicExploiter(WebRCE): except Exception as e: print('[!] Connection Error') print(e) + + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'url': url, 'service': 'Weblogic'}).send() return True def add_vulnerable_urls(self, urls, stop_checking=False): diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index 66cc30fa9..f92e23639 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -10,6 +10,8 @@ from infection_monkey.exploit.tools import SmbTools, WmiTools, AccessDeniedExcep get_monkey_depth, build_monkey_commandline from infection_monkey.model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS from common.utils.exploit_enum import ExploitType +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus LOG = logging.getLogger(__name__) @@ -103,6 +105,9 @@ class WmiExploiter(HostExploiter): if (0 != result.ProcessId) and (0 == result.ReturnValue): LOG.info("Executed dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)", remote_full_path, self.host, result.ProcessId, result.ReturnValue, cmdline) + + VictimHostTelem('T1210', ScanStatus.USED.value, + self.host, {'port': 'unknown', 'service': 'WMI'}).send() success = True else: LOG.debug("Error executing dropper '%s' on remote victim %r (pid=%d, exit_code=%d, cmdline=%r)", diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index e80e15396..2ec3e5d1f 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -17,6 +17,8 @@ from infection_monkey.system_info import SystemInfoCollector from infection_monkey.system_singleton import SystemSingleton from infection_monkey.windows_upgrader import WindowsUpgrader from infection_monkey.post_breach.post_breach_handler import PostBreach +from common.utils.attack_utils import ScanStatus +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem __author__ = 'itamar' diff --git a/monkey/infection_monkey/network/elasticfinger.py b/monkey/infection_monkey/network/elasticfinger.py index 3d62de687..f9f869ce9 100644 --- a/monkey/infection_monkey/network/elasticfinger.py +++ b/monkey/infection_monkey/network/elasticfinger.py @@ -8,6 +8,8 @@ from requests.exceptions import Timeout, ConnectionError import infection_monkey.config from infection_monkey.model.host import VictimHost from infection_monkey.network import HostFinger +from common.utils.attack_utils import ScanStatus +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem ES_PORT = 9200 ES_SERVICE = 'elastic-search-9200' @@ -39,6 +41,8 @@ class ElasticFinger(HostFinger): host.services[ES_SERVICE]['cluster_name'] = data['cluster_name'] host.services[ES_SERVICE]['name'] = data['name'] host.services[ES_SERVICE]['version'] = data['version']['number'] + VictimHostTelem('T1210', ScanStatus.SCANNED.value, + host, {'port': ES_PORT, 'service': 'Elastic'}).send() return True except Timeout: LOG.debug("Got timeout while trying to read header information") diff --git a/monkey/infection_monkey/network/httpfinger.py b/monkey/infection_monkey/network/httpfinger.py index 829c6b1b5..1b686f110 100644 --- a/monkey/infection_monkey/network/httpfinger.py +++ b/monkey/infection_monkey/network/httpfinger.py @@ -1,6 +1,8 @@ import infection_monkey.config from infection_monkey.network import HostFinger from infection_monkey.model.host import VictimHost +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus import logging LOG = logging.getLogger(__name__) @@ -40,6 +42,8 @@ class HTTPFinger(HostFinger): host.services['tcp-' + port[1]]['name'] = 'http' host.services['tcp-' + port[1]]['data'] = (server,ssl) LOG.info("Port %d is open on host %s " % (port[0], host)) + VictimHostTelem('T1210', ScanStatus.SCANNED.value, + host, {'port': port[0], 'service': 'HTTP/HTTPS'}).send() break # https will be the same on the same port except Timeout: pass diff --git a/monkey/infection_monkey/network/mssql_fingerprint.py b/monkey/infection_monkey/network/mssql_fingerprint.py index 75fde7465..08fc62e7a 100644 --- a/monkey/infection_monkey/network/mssql_fingerprint.py +++ b/monkey/infection_monkey/network/mssql_fingerprint.py @@ -4,6 +4,8 @@ import socket from infection_monkey.model.host import VictimHost from infection_monkey.network import HostFinger import infection_monkey.config +from common.utils.attack_utils import ScanStatus +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem __author__ = 'Maor Rayzin' @@ -68,6 +70,8 @@ class MSSQLFinger(HostFinger): # Loop through the server data instances_list = data[3:].decode().split(';;') LOG.info('{0} MSSQL instances found'.format(len(instances_list))) + VictimHostTelem('T1210', ScanStatus.SCANNED.value, + host, {'port': MSSQLFinger.SQL_BROWSER_DEFAULT_PORT, 'service': 'MsSQL'}).send() for instance in instances_list: instance_info = instance.split(';') if len(instance_info) > 1: diff --git a/monkey/infection_monkey/network/mysqlfinger.py b/monkey/infection_monkey/network/mysqlfinger.py index 70080c12b..05c5e9522 100644 --- a/monkey/infection_monkey/network/mysqlfinger.py +++ b/monkey/infection_monkey/network/mysqlfinger.py @@ -5,6 +5,8 @@ import infection_monkey.config from infection_monkey.model.host import VictimHost from infection_monkey.network import HostFinger from infection_monkey.network.tools import struct_unpack_tracker, struct_unpack_tracker_string +from infection_monkey.transport.attack_telems.victim_host_telem import VictimHostTelem +from common.utils.attack_utils import ScanStatus MYSQL_PORT = 3306 SQL_SERVICE = 'mysqld-3306' @@ -59,7 +61,8 @@ class MySQLFinger(HostFinger): host.services[SQL_SERVICE]['minor_version'] = version[1] host.services[SQL_SERVICE]['build_version'] = version[2] thread_id, curpos = struct_unpack_tracker(data, curpos, "{val.map(x => {x} )}; -}; +import ReactTable from "react-table"; -let renderMachine = function (val, index, exploited=false) { +let renderMachine = function (val) { return ( -
- {renderArray(val.ip_addresses)} - {(val.domain_name ? " (".concat(val.domain_name, ")") : " (".concat(val.label, ")"))} : - {exploited ? renderArray(val.exploits) : renderArray(val.services)} -
+ {val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")} ) }; +let renderPort = function (service){ + if(service.url){ + return service.url + } else { + return service.port + } +}; + +const columns = [ + { + columns: [ + {Header: 'Machine', id: 'machine', accessor: x => renderMachine(x), style: { 'whiteSpace': 'unset' }, width: 200}, + {Header: 'Time', id: 'time', accessor: x => x.time, style: { 'whiteSpace': 'unset' }, width: 170}, + {Header: 'Port/url', id: 'port', accessor: x =>renderPort(x), style: { 'whiteSpace': 'unset' }}, + {Header: 'Service', id: 'service', accessor: x => x.service, style: { 'whiteSpace': 'unset' }} + ] + } +]; + class T1210 extends React.Component { - renderScannedMachines = (machines) => { - let content = []; - for (let i = 0; i < machines.length; i++ ){ - if (machines[i].services.length !== 0){ - content.push(renderMachine(machines[i], i)) - } - } - return
{content}
; - }; - - renderExploitedMachines = (machines) => { - let content = []; - for (let i = 0; i < machines.length; i++ ){ - if (machines[i].exploits.length !== 0){ - content.push(renderMachine(machines[i], i, true)) - } - } - return
{content}
; - }; - constructor(props) { super(props); } + renderFoundServices(data) { + return ( +
+
+
Found services:
+ +
) + } + + renderExploitedServices(data) { + return ( +
+
+
Exploited services:
+ +
) + } + render() { return (
{this.props.data.message}
- {this.props.data.scanned_machines.length > 0 ?
Found services:
: ''} - {this.renderScannedMachines(this.props.data.scanned_machines)} - {this.props.data.exploited_machines.length > 0 ?
Successful exploiters:
: ''} - {this.renderExploitedMachines(this.props.data.exploited_machines)} + {this.props.data.found_services.length > 0 ? + this.renderFoundServices(this.props.data.found_services) : ''} + {this.props.data.exploited_services.length > 0 ? + this.renderExploitedServices(this.props.data.exploited_services) : ''}
To get more info about scanned and exploited machines view standard report.