Merge pull request #955 from mssalvatore/819/icmp-cross-segment-report

819/icmp cross segment report

Fixes #819
This commit is contained in:
Mike Salvatore 2021-02-03 10:13:10 -05:00 committed by GitHub
commit 8f7a0aeb1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 19 deletions

View File

@ -7,6 +7,7 @@ class VictimHost(object):
self.domain_name = str(domain_name) self.domain_name = str(domain_name)
self.os = {} self.os = {}
self.services = {} self.services = {}
self.icmp = False
self.monkey_exe = None self.monkey_exe = None
self.default_tunnel = None self.default_tunnel = None
self.default_server = None self.default_server = None
@ -40,7 +41,7 @@ class VictimHost(object):
victim += "] Services - [" victim += "] Services - ["
for k, v in list(self.services.items()): for k, v in list(self.services.items()):
victim += "%s-%s " % (k, v) victim += "%s-%s " % (k, v)
victim += '] ' victim += '] ICMP: %s ' % (self.icmp)
victim += "target monkey: %s" % self.monkey_exe victim += "target monkey: %s" % self.monkey_exe
return victim return victim

View File

@ -62,6 +62,9 @@ class PingScanner(HostScanner, HostFinger):
host.os['type'] = 'linux' host.os['type'] = 'linux'
else: # as far we we know, could also be OSX/BSD but lets handle that when it comes up. else: # as far we we know, could also be OSX/BSD but lets handle that when it comes up.
host.os['type'] = 'windows' host.os['type'] = 'windows'
host.icmp = True
return True return True
except Exception as exc: except Exception as exc:
LOG.debug("Error parsing ping fingerprint: %s", exc) LOG.debug("Error parsing ping fingerprint: %s", exc)

View File

@ -510,6 +510,7 @@ class ReportService:
'hostname': monkey['hostname'], 'hostname': monkey['hostname'],
'target': target_ip, 'target': target_ip,
'services': scan['data']['machine']['services'], 'services': scan['data']['machine']['services'],
'icmp': scan['data']['machine']['icmp'],
'is_self': False 'is_self': False
}) })
@ -544,7 +545,7 @@ class ReportService:
@staticmethod @staticmethod
def get_cross_segment_issues(): def get_cross_segment_issues():
scans = mongo.db.telemetry.find({'telem_category': 'scan'}, scans = mongo.db.telemetry.find({'telem_category': 'scan'},
{'monkey_guid': 1, 'data.machine.ip_addr': 1, 'data.machine.services': 1}) {'monkey_guid': 1, 'data.machine.ip_addr': 1, 'data.machine.services': 1, 'data.machine.icmp': 1})
cross_segment_issues = [] cross_segment_issues = []

View File

@ -451,25 +451,64 @@ class ReportPageComponent extends AuthComponent {
} }
generateCrossSegmentIssue(crossSegmentIssue) { generateCrossSegmentIssue(crossSegmentIssue) {
let crossSegmentIssueOverview = 'Communication possible from ' + crossSegmentIssue['source_subnet'] + ' to ' + crossSegmentIssue['target_subnet'] let crossSegmentIssueOverview = 'Communication possible from '
return <li key={crossSegmentIssueOverview}> + `${crossSegmentIssue['source_subnet']} to ${crossSegmentIssue['target_subnet']}`;
return (
<li key={crossSegmentIssueOverview}>
{crossSegmentIssueOverview} {crossSegmentIssueOverview}
<CollapsibleWellComponent> <CollapsibleWellComponent>
<ul> <ul className='cross-segment-issues'>
{crossSegmentIssue['issues'].map(x => {crossSegmentIssue['issues'].map(
x['is_self'] ? issue => this.generateCrossSegmentIssueListItem(issue)
<li key={x['hostname']}>
{'Machine ' + x['hostname'] + ' has both ips: ' + x['source'] + ' and ' + x['target']}
</li>
:
<li key={x['source'] + x['target']}>
{'IP ' + x['source'] + ' (' + x['hostname'] + ') connected to IP ' + x['target']
+ ' using the services: ' + Object.keys(x['services']).join(', ')}
</li>
)} )}
</ul> </ul>
</CollapsibleWellComponent> </CollapsibleWellComponent>
</li>; </li>
);
}
generateCrossSegmentIssueListItem(issue) {
if (issue['is_self']) {
return this.generateCrossSegmentSingleHostMessage(issue);
}
return this.generateCrossSegmentMultiHostMessage(issue);
}
generateCrossSegmentSingleHostMessage(issue) {
return (
<li key={issue['hostname']}>
{`Machine ${issue['hostname']} has both ips: ${issue['source']} and ${issue['target']}`}
</li>
);
}
generateCrossSegmentMultiHostMessage(issue) {
return (
<li key={issue['source'] + issue['target']}>
IP {issue['source']} ({issue['hostname']}) was able to communicate with
IP {issue['target']} using:
<ul>
{issue['icmp'] && <li key='icmp'>ICMP</li>}
{this.generateCrossSegmentServiceListItems(issue)}
</ul>
</li>
);
}
generateCrossSegmentServiceListItems(issue) {
let service_list_items = [];
for (const [service, info] of Object.entries(issue['services'])) {
service_list_items.push(
<li key={service}>
<span className='cross-segment-service'>{service}</span> ({info['display_name']})
</li>
);
}
return service_list_items;
} }
generateShellshockPathListBadges(paths) { generateShellshockPathListBadges(paths) {

View File

@ -76,3 +76,12 @@ div.report-wrapper .nav-tabs > .nav-item > a:hover:not(.active), .nav-tabs > .n
text-decoration: none; text-decoration: none;
background-color: $light-gray; background-color: $light-gray;
} }
ul.cross-segment-issues {
list-style-type: none;
padding: 0px;
margin: 0px;
}
span.cross-segment-service {
text-transform: uppercase;
}