From 7f5c07c1fd4e9b5eab7cd13e828efcab9fa5b4e2 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Mon, 6 May 2019 14:57:17 +0300 Subject: [PATCH] Refactored fingerprint scanners to add port on init --- monkey/common/utils/code_utils.py | 10 +++ monkey/infection_monkey/exploit/sambacry.py | 5 +- monkey/infection_monkey/network/__init__.py | 13 +--- .../infection_monkey/network/elasticfinger.py | 3 +- monkey/infection_monkey/network/httpfinger.py | 3 +- .../network/mssql_fingerprint.py | 3 +- .../infection_monkey/network/mysqlfinger.py | 3 +- monkey/infection_monkey/network/smbfinger.py | 3 +- monkey/infection_monkey/network/sshfinger.py | 3 +- .../infection_monkey/network/tcp_scanner.py | 5 +- monkey/monkey_island/cc/resources/root.py | 4 +- .../cc/services/attack/attack_config.py | 6 +- .../cc/services/attack/attack_report.py | 14 ++-- .../attack/technique_reports/T1197.py | 38 +++++------ .../attack/technique_reports/T1210.py | 67 +++++++++++-------- .../attack/technique_reports/__init__.py | 64 +++++++++++++++++- .../technique_reports/technique_service.py | 37 ---------- .../cc/ui/src/components/Main.js | 12 ---- .../cc/ui/src/components/attack/T1197.js | 46 ------------- .../src/components/attack/techniques/T1197.js | 49 ++++++++++++++ .../attack/{ => techniques}/T1210.js | 2 +- .../cc/ui/src/components/pages/ReportPage.js | 17 +++++ .../AttackReport.js} | 13 +--- 23 files changed, 224 insertions(+), 196 deletions(-) create mode 100644 monkey/common/utils/code_utils.py delete mode 100644 monkey/monkey_island/cc/services/attack/technique_reports/technique_service.py delete mode 100644 monkey/monkey_island/cc/ui/src/components/attack/T1197.js create mode 100644 monkey/monkey_island/cc/ui/src/components/attack/techniques/T1197.js rename monkey/monkey_island/cc/ui/src/components/attack/{ => techniques}/T1210.js (98%) rename monkey/monkey_island/cc/ui/src/components/{pages/AttackReportPage.js => report-components/AttackReport.js} (94%) diff --git a/monkey/common/utils/code_utils.py b/monkey/common/utils/code_utils.py new file mode 100644 index 000000000..d6d407706 --- /dev/null +++ b/monkey/common/utils/code_utils.py @@ -0,0 +1,10 @@ + + +# abstract, static method decorator +class abstractstatic(staticmethod): + __slots__ = () + + def __init__(self, function): + super(abstractstatic, self).__init__(function) + function.__isabstractmethod__ = True + __isabstractmethod__ = True diff --git a/monkey/infection_monkey/exploit/sambacry.py b/monkey/infection_monkey/exploit/sambacry.py index 7c4d7790a..4abdf8f33 100644 --- a/monkey/infection_monkey/exploit/sambacry.py +++ b/monkey/infection_monkey/exploit/sambacry.py @@ -89,7 +89,10 @@ class SambaCryExploiter(HostExploiter): LOG.info( "Shares triggered successfully on host %s: %s" % ( self.host.ip_addr, str(successfully_triggered_shares))) - self.add_vuln_port(str(writable_shares_creds_dict)) + # TODO: add vulnerable url + #for share, fullpath in successfully_triggered_shares: + # self.add_vuln_url("smb://@:/" % False, + # self.host.ip_addr, False, share) return True else: LOG.info("No shares triggered successfully on host %s" % self.host.ip_addr) diff --git a/monkey/infection_monkey/network/__init__.py b/monkey/infection_monkey/network/__init__.py index b47d4ebca..59a6d01d6 100644 --- a/monkey/infection_monkey/network/__init__.py +++ b/monkey/infection_monkey/network/__init__.py @@ -18,19 +18,10 @@ class HostFinger(object): def _SCANNED_SERVICE(self): pass - def init_service(self, services, service_key): + def init_service(self, services, service_key, port): services[service_key] = {} services[service_key]['display_name'] = self._SCANNED_SERVICE - - def add_found_port(self, services, port, key=None): - if key: - services[key]['port'] = port - else: - for service in services: - if services[service]['display_name'] == self._SCANNED_SERVICE: - service[service]['port'] = port - return - raise KeyError + services[service_key]['port'] = port @abstractmethod def get_host_fingerprint(self, host): diff --git a/monkey/infection_monkey/network/elasticfinger.py b/monkey/infection_monkey/network/elasticfinger.py index 710479cb8..31ce6e24a 100644 --- a/monkey/infection_monkey/network/elasticfinger.py +++ b/monkey/infection_monkey/network/elasticfinger.py @@ -36,11 +36,10 @@ class ElasticFinger(HostFinger): url = 'http://%s:%s/' % (host.ip_addr, ES_PORT) with closing(requests.get(url, timeout=ES_HTTP_TIMEOUT)) as req: data = json.loads(req.text) - self.init_service(host.services, ES_SERVICE) + self.init_service(host.services, ES_SERVICE, ES_PORT) host.services[ES_SERVICE]['cluster_name'] = data['cluster_name'] host.services[ES_SERVICE]['name'] = data['name'] host.services[ES_SERVICE]['version'] = data['version']['number'] - self.add_found_port(host.services, ES_PORT) 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 1bcc70fb5..30292d99f 100644 --- a/monkey/infection_monkey/network/httpfinger.py +++ b/monkey/infection_monkey/network/httpfinger.py @@ -37,9 +37,8 @@ class HTTPFinger(HostFinger): with closing(head(url, verify=False, timeout=1)) as req: server = req.headers.get('Server') ssl = True if 'https://' in url else False - self.init_service(host.services, ('tcp-' + port[1])) + self.init_service(host.services, ('tcp-' + port[1]), port[0]) host.services['tcp-' + port[1]]['name'] = 'http' - self.add_found_port(host.services, port[0], ('tcp-' + port[1])) host.services['tcp-' + port[1]]['data'] = (server,ssl) LOG.info("Port %d is open on host %s " % (port[0], host)) break # https will be the same on the same port diff --git a/monkey/infection_monkey/network/mssql_fingerprint.py b/monkey/infection_monkey/network/mssql_fingerprint.py index f99f92f5c..7b666bf9f 100644 --- a/monkey/infection_monkey/network/mssql_fingerprint.py +++ b/monkey/infection_monkey/network/mssql_fingerprint.py @@ -63,7 +63,7 @@ class MSSQLFinger(HostFinger): sock.close() return False - self.init_service(host.services, self._SCANNED_SERVICE) + self.init_service(host.services, self._SCANNED_SERVICE, MSSQLFinger.SQL_BROWSER_DEFAULT_PORT) # Loop through the server data instances_list = data[3:].decode().split(';;') @@ -76,7 +76,6 @@ class MSSQLFinger(HostFinger): # Each instance's info is nested under its own name, if there are multiple instances # each will appear under its own name host.services[self._SCANNED_SERVICE][instance_info[1]][instance_info[i - 1]] = instance_info[i] - self.add_found_port(host.services, MSSQLFinger.SQL_BROWSER_DEFAULT_PORT) # Close the socket sock.close() diff --git a/monkey/infection_monkey/network/mysqlfinger.py b/monkey/infection_monkey/network/mysqlfinger.py index 94077f684..123f0ae47 100644 --- a/monkey/infection_monkey/network/mysqlfinger.py +++ b/monkey/infection_monkey/network/mysqlfinger.py @@ -51,14 +51,13 @@ class MySQLFinger(HostFinger): version, curpos = struct_unpack_tracker_string(data, curpos) # special coded to solve string parsing version = version[0] - self.init_service(host.services, SQL_SERVICE) + self.init_service(host.services, SQL_SERVICE, MYSQL_PORT) host.services[SQL_SERVICE]['version'] = version version = version.split('-')[0].split('.') host.services[SQL_SERVICE]['major_version'] = version[0] host.services[SQL_SERVICE]['minor_version'] = version[1] host.services[SQL_SERVICE]['build_version'] = version[2] thread_id, curpos = struct_unpack_tracker(data, curpos, " -
  • - - 5. - ATT&CK report - {this.state.completedSteps.attack_report_done ? - - : ''} - -
  • @@ -196,7 +185,6 @@ class AppComponent extends AuthComponent { {this.renderRoute('/infection/telemetry', )} {this.renderRoute('/start-over', )} {this.renderRoute('/report', )} - {this.renderRoute('/attack_report', )} {this.renderRoute('/license', )} diff --git a/monkey/monkey_island/cc/ui/src/components/attack/T1197.js b/monkey/monkey_island/cc/ui/src/components/attack/T1197.js deleted file mode 100644 index 3b0e09e7c..000000000 --- a/monkey/monkey_island/cc/ui/src/components/attack/T1197.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import '../../styles/Collapse.scss' -import ReactTable from "react-table"; - -let renderMachine = function (val) { - return ( - {val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")} - ) -}; - -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: 'Usage', id: 'usage', accessor: x => x.usage, style: { 'whiteSpace': 'unset' }} - ] - } -]; - -class T1210 extends React.Component { - - constructor(props) { - super(props); - } - - render() { - return ( -
    -
    -
    {this.props.data.message}
    - {this.props.data.bits_jobs.length > 0 ?
    BITS jobs were used in these machines:
    : ''} -
    -
    - -
    - ); - } -} - -export default T1210; diff --git a/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1197.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1197.js new file mode 100644 index 000000000..b243eb644 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1197.js @@ -0,0 +1,49 @@ +import React from 'react'; +import '../../../styles/Collapse.scss' +import ReactTable from "react-table"; + + +class T1210 extends React.Component { + + constructor(props) { + super(props); + this.columns = [ {Header: 'Machine', + id: 'machine', accessor: x => T1210.renderMachine(x), + style: { 'whiteSpace': 'unset' }, + width: 200}, + {Header: 'Time', + id: 'time', accessor: x => x.time, + style: { 'whiteSpace': 'unset' }, + width: 170}, + {Header: 'Usage', + id: 'usage', accessor: x => x.usage, + style: { 'whiteSpace': 'unset' }} + ] + } + + static renderMachine = (val) => { + return ( + {val.ip_addr} {(val.domain_name ? " (".concat(val.domain_name, ")") : "")} + ) + }; + + render() { + return ( +
    +
    +
    {this.props.data.message}
    + {this.props.data.bits_jobs.length > 0 ?
    BITS jobs were used in these machines:
    : ''} +
    +
    + +
    + ); + } +} + +export default T1210; diff --git a/monkey/monkey_island/cc/ui/src/components/attack/T1210.js b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1210.js similarity index 98% rename from monkey/monkey_island/cc/ui/src/components/attack/T1210.js rename to monkey/monkey_island/cc/ui/src/components/attack/techniques/T1210.js index 2fd5b33e0..acc5af02b 100644 --- a/monkey/monkey_island/cc/ui/src/components/attack/T1210.js +++ b/monkey/monkey_island/cc/ui/src/components/attack/techniques/T1210.js @@ -1,5 +1,5 @@ import React from 'react'; -import '../../styles/Collapse.scss' +import '../../../styles/Collapse.scss' import {Link} from "react-router-dom"; import ReactTable from "react-table"; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js index 43be6367c..125efd264 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ReportPage.js @@ -11,6 +11,7 @@ import {Line} from 'rc-progress'; import AuthComponent from '../AuthComponent'; import PassTheHashMapPageComponent from "./PassTheHashMapPage"; import StrongUsers from "components/report-components/StrongUsers"; +import AttackReport from "components/report-components/AttackReport"; let guardicoreLogoImage = require('../../images/guardicore-logo.png'); let monkeyLogoImage = require('../../images/monkey-icon.svg'); @@ -140,6 +141,7 @@ class ReportPageComponent extends AuthComponent { {this.generateReportFindingsSection()} {this.generateReportRecommendationsSection()} {this.generateReportGlanceSection()} + {this.generateAttackSection()} {this.generateReportFooter()}
    @@ -503,6 +505,21 @@ class ReportPageComponent extends AuthComponent { ); } + generateAttackSection() { + return (
    +

    + ATT&CK report +

    +

    + This report shows information about ATT&CK techniques used by Infection Monkey. +

    +
    + +
    +
    +
    ) + } + generateReportFooter() { return (