Everything implemented on backend
This commit is contained in:
parent
82e30040eb
commit
ce10ef00e4
|
@ -292,3 +292,21 @@ class NodeService:
|
||||||
{'_id': node_id},
|
{'_id': node_id},
|
||||||
{'$push': {'creds': creds}}
|
{'$push': {'creds': creds}}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_node_or_monkey_by_ip(ip_address):
|
||||||
|
node = NodeService.get_node_by_ip(ip_address)
|
||||||
|
if node is not None:
|
||||||
|
return node
|
||||||
|
return NodeService.get_monkey_by_ip(ip_address)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_node_or_monkey_by_id(node_id):
|
||||||
|
node = NodeService.get_node_by_id(node_id)
|
||||||
|
if node is not None:
|
||||||
|
return node
|
||||||
|
return NodeService.get_monkey_by_id(node_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_node_hostname(node):
|
||||||
|
return node['hostname'] if 'hostname' in node else node['os']['version']
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import datetime
|
import ipaddress
|
||||||
|
|
||||||
from cc.database import mongo
|
from cc.database import mongo
|
||||||
from cc.services.config import ConfigService
|
|
||||||
from cc.services.edge import EdgeService
|
from cc.services.edge import EdgeService
|
||||||
from cc.services.node import NodeService
|
from cc.services.node import NodeService
|
||||||
|
from cc.utils import local_ip_addresses, get_subnets
|
||||||
|
|
||||||
__author__ = "itay.mizeretz"
|
__author__ = "itay.mizeretz"
|
||||||
|
|
||||||
|
@ -38,25 +38,20 @@ class ReportService:
|
||||||
st += "%d minutes and %d seconds" % (minutes, seconds)
|
st += "%d minutes and %d seconds" % (minutes, seconds)
|
||||||
return st
|
return st
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_breach_count():
|
|
||||||
return mongo.db.edge.count({'exploits.result': True})
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_successful_exploit_types():
|
|
||||||
exploit_types = mongo.db.command({'distinct': 'edge', 'key': 'exploits.exploiter'})['values']
|
|
||||||
return [exploit for exploit in exploit_types if ReportService.did_exploit_type_succeed(exploit)]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_tunnels():
|
def get_tunnels():
|
||||||
return [
|
return [
|
||||||
(NodeService.get_monkey_label_by_id(tunnel['_id']), NodeService.get_monkey_label_by_id(tunnel['tunnel']))
|
{
|
||||||
|
'type': 'tunnel',
|
||||||
|
'origin': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_id(tunnel['_id'])),
|
||||||
|
'dest': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_id(tunnel['tunnel']))
|
||||||
|
}
|
||||||
for tunnel in mongo.db.monkey.find({'tunnel': {'$exists': True}}, {'tunnel': 1})]
|
for tunnel in mongo.db.monkey.find({'tunnel': {'$exists': True}}, {'tunnel': 1})]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_scanned():
|
def get_scanned():
|
||||||
nodes =\
|
nodes = \
|
||||||
[NodeService.get_displayed_node_by_id(node['_id']) for node in mongo.db.node.find({}, {'_id': 1})]\
|
[NodeService.get_displayed_node_by_id(node['_id']) for node in mongo.db.node.find({}, {'_id': 1})] \
|
||||||
+ [NodeService.get_displayed_node_by_id(monkey['_id']) for monkey in mongo.db.monkey.find({}, {'_id': 1})]
|
+ [NodeService.get_displayed_node_by_id(monkey['_id']) for monkey in mongo.db.monkey.find({}, {'_id': 1})]
|
||||||
nodes = [
|
nodes = [
|
||||||
{
|
{
|
||||||
|
@ -73,32 +68,17 @@ class ReportService:
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_reused_passwords():
|
|
||||||
password_dict = {}
|
|
||||||
password_list = ConfigService.get_config_value(['basic', 'credentials', 'exploit_password_list'])
|
|
||||||
for password in password_list:
|
|
||||||
machines_with_password =\
|
|
||||||
[
|
|
||||||
NodeService.get_monkey_label_by_id(node['_id'])
|
|
||||||
for node in mongo.db.monkey.find({'creds.password': password}, {'_id': 1})
|
|
||||||
]
|
|
||||||
if len(machines_with_password) >= 2:
|
|
||||||
password_dict[password] = machines_with_password
|
|
||||||
|
|
||||||
return password_dict
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_exploited():
|
def get_exploited():
|
||||||
exploited =\
|
exploited = \
|
||||||
[NodeService.get_displayed_node_by_id(monkey['_id']) for monkey in mongo.db.monkey.find({}, {'_id': 1})
|
[NodeService.get_displayed_node_by_id(monkey['_id']) for monkey in mongo.db.monkey.find({}, {'_id': 1})
|
||||||
if not NodeService.get_monkey_manual_run(NodeService.get_monkey_by_id(monkey['_id']))]\
|
if not NodeService.get_monkey_manual_run(NodeService.get_monkey_by_id(monkey['_id']))] \
|
||||||
+ [NodeService.get_displayed_node_by_id(node['_id'])
|
+ [NodeService.get_displayed_node_by_id(node['_id'])
|
||||||
for node in mongo.db.node.find({'exploited': True}, {'_id': 1})]
|
for node in mongo.db.node.find({'exploited': True}, {'_id': 1})]
|
||||||
|
|
||||||
exploited = [
|
exploited = [
|
||||||
{
|
{
|
||||||
'label': monkey['hostname'] if 'hostname' in monkey else monkey['os']['version'],
|
'label': NodeService.get_node_hostname(monkey),
|
||||||
'ip_addresses': monkey['ip_addresses'],
|
'ip_addresses': monkey['ip_addresses'],
|
||||||
'exploits': [exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]
|
'exploits': [exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]
|
||||||
}
|
}
|
||||||
|
@ -130,6 +110,146 @@ class ReportService:
|
||||||
)
|
)
|
||||||
return creds
|
return creds
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_general_exploit(exploit):
|
||||||
|
ip_addr = exploit['data']['machine']['ip_addr']
|
||||||
|
return {'machine': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_ip(ip_addr)),
|
||||||
|
'ip_address': ip_addr}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_general_creds_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_exploit(exploit)
|
||||||
|
|
||||||
|
for attempt in exploit['data']['attempts']:
|
||||||
|
if attempt['result']:
|
||||||
|
processed_exploit['username'] = attempt['user']
|
||||||
|
if len(attempt['password']) > 0:
|
||||||
|
processed_exploit['type'] = 'password'
|
||||||
|
else:
|
||||||
|
processed_exploit['type'] = 'hash'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_smb_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||||
|
if processed_exploit['type'] == 'password':
|
||||||
|
processed_exploit['type'] = 'smb_password'
|
||||||
|
else:
|
||||||
|
processed_exploit['type'] = 'smb_pth'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_wmi_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||||
|
if processed_exploit['type'] == 'password':
|
||||||
|
processed_exploit['type'] = 'wmi_password'
|
||||||
|
else:
|
||||||
|
processed_exploit['type'] = 'wmi_pth'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_ssh_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'ssh'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_rdp_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'rdp'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_sambacry_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_creds_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'sambacry'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_elastic_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'elastic'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_conficker_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'conficker'
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_shellshock_exploit(exploit):
|
||||||
|
processed_exploit = ReportService.process_general_exploit(exploit)
|
||||||
|
processed_exploit['type'] = 'shellshock'
|
||||||
|
urls = exploit['data']['info']['vulnerable_urls']
|
||||||
|
processed_exploit['port'] = urls[0].split(':')[2].split('/')[0]
|
||||||
|
processed_exploit['paths'] = ['/' + url.split(':')[2].split('/')[1] for url in urls]
|
||||||
|
return processed_exploit
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def process_exploit(exploit):
|
||||||
|
exploiter_type = exploit['data']['exploiter']
|
||||||
|
if exploiter_type == 'SmbExploiter':
|
||||||
|
return ReportService.process_smb_exploit(exploit)
|
||||||
|
if exploiter_type == 'WmiExploiter':
|
||||||
|
return ReportService.process_wmi_exploit(exploit)
|
||||||
|
if exploiter_type == 'SSHExploiter':
|
||||||
|
return ReportService.process_ssh_exploit(exploit)
|
||||||
|
if exploiter_type == 'RdpExploiter':
|
||||||
|
return ReportService.process_rdp_exploit(exploit)
|
||||||
|
if exploiter_type == 'SambaCryExploiter':
|
||||||
|
return ReportService.process_sambacry_exploit(exploit)
|
||||||
|
if exploiter_type == 'ElasticGroovyExploiter':
|
||||||
|
return ReportService.process_elastic_exploit(exploit)
|
||||||
|
if exploiter_type == 'Ms08_067_Exploiter':
|
||||||
|
return ReportService.process_conficker_exploit(exploit)
|
||||||
|
if exploiter_type == 'ShellShockExploiter':
|
||||||
|
return ReportService.process_shellshock_exploit(exploit)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_exploits():
|
||||||
|
return [ReportService.process_exploit(exploit) for
|
||||||
|
exploit in mongo.db.telemetry.find({'telem_type': 'exploit', 'data.result': True})]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_monkey_subnets(monkey_guid):
|
||||||
|
return \
|
||||||
|
[
|
||||||
|
ipaddress.ip_interface(unicode(network['addr'] + '/' + network['netmask'])).network
|
||||||
|
for network in
|
||||||
|
mongo.db.telemetry.find_one(
|
||||||
|
{'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid},
|
||||||
|
{'data.network_info.networks': 1}
|
||||||
|
)['data']['network_info']['networks']
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_cross_segment_issues():
|
||||||
|
issues = []
|
||||||
|
island_ips = local_ip_addresses()
|
||||||
|
for monkey in mongo.db.monkey.find({'tunnel': {'$exists': False}}, {'tunnel': 1, 'guid': 1, 'hostname': 1}):
|
||||||
|
found_good_ip = False
|
||||||
|
monkey_subnets = ReportService.get_monkey_subnets(monkey['guid'])
|
||||||
|
for subnet in monkey_subnets:
|
||||||
|
for ip in island_ips:
|
||||||
|
if ipaddress.ip_address(unicode(ip)) in subnet:
|
||||||
|
found_good_ip = True
|
||||||
|
break
|
||||||
|
if found_good_ip:
|
||||||
|
break
|
||||||
|
if not found_good_ip:
|
||||||
|
issues.append(
|
||||||
|
{'type': 'cross_segment', 'machine': monkey['hostname'],
|
||||||
|
'networks': [str(subnet) for subnet in monkey_subnets],
|
||||||
|
'server_networks': [str(subnet) for subnet in get_subnets()]}
|
||||||
|
)
|
||||||
|
|
||||||
|
return issues
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_issues():
|
||||||
|
return ReportService.get_exploits() + ReportService.get_tunnels() + ReportService.get_cross_segment_issues()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_report():
|
def get_report():
|
||||||
return \
|
return \
|
||||||
|
@ -149,42 +269,9 @@ class ReportService:
|
||||||
},
|
},
|
||||||
'recommendations':
|
'recommendations':
|
||||||
{
|
{
|
||||||
'issues':
|
'issues': ReportService.get_issues()
|
||||||
[
|
|
||||||
{'type': 'smb_password', 'machine': 'Monkey-SMB',
|
|
||||||
'ip_addresses': ['192.168.0.1', '10.0.0.18'], 'username': 'Administrator'},
|
|
||||||
{'type': 'smb_pth', 'machine': 'Monkey-SMB2', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'username': 'Administrator'},
|
|
||||||
{'type': 'wmi_password', 'machine': 'Monkey-WMI',
|
|
||||||
'ip_addresses': ['192.168.0.1', '10.0.0.18'], 'username': 'Administrator'},
|
|
||||||
{'type': 'wmi_pth', 'machine': 'Monkey-WMI2', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'username': 'Administrator'},
|
|
||||||
{'type': 'ssh', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'username': 'Administrator'},
|
|
||||||
{'type': 'rdp', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'username': 'Administrator'},
|
|
||||||
{'type': 'sambacry', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'username': 'Administrator'},
|
|
||||||
{'type': 'elastic', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18']},
|
|
||||||
{'type': 'shellshock', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18'],
|
|
||||||
'port': 8080, 'paths': ['/cgi/backserver.cgi', '/cgi/login.cgi']},
|
|
||||||
{'type': 'conficker', 'machine': 'Monkey-SMB', 'ip_addresses': ['192.168.0.1', '10.0.0.18']},
|
|
||||||
{'type': 'cross_segment', 'machine': 'Monkey-SMB', 'network': '192.168.0.0/24',
|
|
||||||
'server_network': '172.168.0.0/24'},
|
|
||||||
{'type': 'tunnel', 'origin': 'Monkey-SSH', 'dest': 'Monkey-SambaCry'}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# TODO: put implementation in template
|
|
||||||
"""
|
|
||||||
return \
|
|
||||||
{
|
|
||||||
'breach_count': ReportService.get_breach_count(),
|
|
||||||
'successful_exploit_types': ReportService.get_successful_exploit_types(),
|
|
||||||
'tunnels': ReportService.get_tunnels(),
|
|
||||||
'reused_passwords': ReportService.get_reused_passwords()
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def did_exploit_type_succeed(exploit_type):
|
def did_exploit_type_succeed(exploit_type):
|
||||||
|
|
|
@ -65,8 +65,8 @@ class ReportPageComponent extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
generateIpListBadges(ip_addresses) {
|
generateInfoBadges(data_array) {
|
||||||
return ip_addresses.map(ip_address => <span className="label label-info" style={{margin: '2px'}}>{ip_address}</span>);
|
return data_array.map(badge_data => <span className="label label-info" style={{margin: '2px'}}>{badge_data}</span>);
|
||||||
}
|
}
|
||||||
|
|
||||||
generateShellshockPathListBadges(paths) {
|
generateShellshockPathListBadges(paths) {
|
||||||
|
@ -76,7 +76,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSmbPasswordIssue(issue) {
|
generateSmbPasswordIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
||||||
<br />
|
<br />
|
||||||
|
@ -91,7 +91,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSmbPthIssue(issue) {
|
generateSmbPthIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SMB</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span className="label label-success">{issue.username}</span>.
|
The attack succeeded by using a pass-the-hash attack over SMB protocol with user <span className="label label-success">{issue.username}</span>.
|
||||||
<br />
|
<br />
|
||||||
|
@ -106,7 +106,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateWmiPasswordIssue(issue) {
|
generateWmiPasswordIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by authenticating over WMI protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
The attack succeeded by authenticating over WMI protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
||||||
<br />
|
<br />
|
||||||
|
@ -121,7 +121,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateWmiPthIssue(issue) {
|
generateWmiPthIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">WMI</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span className="label label-success">{issue.username}</span>.
|
The attack succeeded by using a pass-the-hash attack over WMI protocol with user <span className="label label-success">{issue.username}</span>.
|
||||||
<br />
|
<br />
|
||||||
|
@ -136,7 +136,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSshIssue(issue) {
|
generateSshIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">SSH</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SSH</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by authenticating over SSH protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
The attack succeeded by authenticating over SSH protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
||||||
<br />
|
<br />
|
||||||
|
@ -151,7 +151,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateRdpIssue(issue) {
|
generateRdpIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">RDP</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">RDP</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by authenticating over RDP protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
The attack succeeded by authenticating over RDP protocol with user <span className="label label-success">{issue.username}</span> and its password.
|
||||||
<br />
|
<br />
|
||||||
|
@ -166,7 +166,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateSambaCryIssue(issue) {
|
generateSambaCryIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">SambaCry</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">SambaCry</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password, and by using the SambaCry vulnerability.
|
The attack succeeded by authenticating over SMB protocol with user <span className="label label-success">{issue.username}</span> and its password, and by using the SambaCry vulnerability.
|
||||||
<br />
|
<br />
|
||||||
|
@ -182,7 +182,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateElasticIssue(issue) {
|
generateElasticIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to an <span className="label label-danger">Elastic Groovy</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to an <span className="label label-danger">Elastic Groovy</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
|
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
|
||||||
<br />
|
<br />
|
||||||
|
@ -197,7 +197,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateShellshockIssue(issue) {
|
generateShellshockIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">ShellShock</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following IP address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">ShellShock</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded because the HTTP server running on port <span className="label label-info">{issue.port}</span> was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
|
The attack succeeded because the HTTP server running on port <span className="label label-info">{issue.port}</span> was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
|
||||||
<br />
|
<br />
|
||||||
|
@ -212,7 +212,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateConfickerIssue(issue) {
|
generateConfickerIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The machine <span className="label label-primary">{issue.machine}</span> with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a <span className="label label-danger">Conficker</span> attack.
|
The machine <span className="label label-primary">{issue.machine}</span> with the following address <span className="label label-info" style={{margin: '2px'}}>{issue.ip_address}</span> was vulnerable to a <span className="label label-danger">Conficker</span> attack.
|
||||||
<br />
|
<br />
|
||||||
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
|
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
|
||||||
<br />
|
<br />
|
||||||
|
@ -227,7 +227,7 @@ class ReportPageComponent extends React.Component {
|
||||||
generateCrossSegmentIssue(issue) {
|
generateCrossSegmentIssue(issue) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
The network can probably be segmented. A monkey instance on <span className="label label-primary">{issue.machine}</span> in the <span className="label label-info">{issue.network}</span> network could directly access the Monkey Island C&C server in the <span className="label label-info">{issue.server_network}</span> network.
|
The network can probably be segmented. A monkey instance on <span className="label label-primary">{issue.machine}</span> in the networks {this.generateInfoBadges(issue.networks)} could directly access the Monkey Island C&C server in the networks {this.generateInfoBadges(issue.server_networks)}.
|
||||||
<br />
|
<br />
|
||||||
In order to protect the network, the following steps should be performed:
|
In order to protect the network, the following steps should be performed:
|
||||||
<ul className="report">
|
<ul className="report">
|
||||||
|
|
|
@ -4,6 +4,7 @@ import sys
|
||||||
import array
|
import array
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
|
import ipaddress
|
||||||
from netifaces import interfaces, ifaddresses, AF_INET
|
from netifaces import interfaces, ifaddresses, AF_INET
|
||||||
|
|
||||||
from cc.database import mongo
|
from cc.database import mongo
|
||||||
|
@ -56,3 +57,11 @@ def local_ip_addresses():
|
||||||
addresses = ifaddresses(interface).get(AF_INET, [])
|
addresses = ifaddresses(interface).get(AF_INET, [])
|
||||||
ip_list.extend([link['addr'] for link in addresses if link['addr'] != '127.0.0.1'])
|
ip_list.extend([link['addr'] for link in addresses if link['addr'] != '127.0.0.1'])
|
||||||
return ip_list
|
return ip_list
|
||||||
|
|
||||||
|
|
||||||
|
def get_subnets():
|
||||||
|
subnets = []
|
||||||
|
for interface in interfaces():
|
||||||
|
addresses = ifaddresses(interface).get(AF_INET, [])
|
||||||
|
subnets.extend([ipaddress.ip_interface(link['addr'] + '/' + link['netmask']).network for link in addresses if link['addr'] != '127.0.0.1'])
|
||||||
|
return subnets
|
||||||
|
|
|
@ -10,3 +10,4 @@ Flask-Pymongo
|
||||||
Flask-Restful
|
Flask-Restful
|
||||||
jsonschema
|
jsonschema
|
||||||
netifaces
|
netifaces
|
||||||
|
ipaddress
|
Loading…
Reference in New Issue