Replaced Conclusive with Failed, and Positive with Passed

This commit is contained in:
Shay Nehmad 2019-08-28 11:59:33 +03:00
parent 04005b14d7
commit dfebf5e841
22 changed files with 153 additions and 178 deletions

View File

@ -16,11 +16,11 @@ DATA = u"Data"
PILLARS = (DATA, PEOPLE, NETWORKS, DEVICES, WORKLOADS, VISIBILITY_ANALYTICS, AUTOMATION_ORCHESTRATION)
STATUS_UNEXECUTED = u"Unexecuted"
STATUS_POSITIVE = u"Positive"
STATUS_PASSED = u"Passed"
STATUS_INCONCLUSIVE = u"Inconclusive"
STATUS_CONCLUSIVE = u"Conclusive"
STATUS_FAILED = u"Failed"
# Don't change order! The statuses are ordered by importance/severity.
ORDERED_TEST_STATUSES = [STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE, STATUS_POSITIVE, STATUS_UNEXECUTED]
ORDERED_TEST_STATUSES = [STATUS_FAILED, STATUS_INCONCLUSIVE, STATUS_PASSED, STATUS_UNEXECUTED]
TEST_DATA_ENDPOINT_ELASTIC = u"unencrypted_data_endpoint_elastic"
TEST_DATA_ENDPOINT_HTTP = u"unencrypted_data_endpoint_http"
@ -61,12 +61,12 @@ TESTS_MAP = {
TEST_SEGMENTATION: {
TEST_EXPLANATION_KEY: u"The Monkey tried to scan and find machines that it can communicate with from the machine it's running on, that belong to different network segments.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_CONCLUSIVE: "Monkey performed cross-segment communication. Check firewall rules and logs.",
STATUS_POSITIVE: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs."
STATUS_FAILED: "Monkey performed cross-segment communication. Check firewall rules and logs.",
STATUS_PASSED: "Monkey couldn't perform cross-segment communication. If relevant, check firewall logs."
},
RECOMMENDATION_KEY: RECOMMENDATION_SEGMENTATION,
PILLARS_KEY: [NETWORKS],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_POSITIVE, STATUS_CONCLUSIVE]
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_PASSED, STATUS_FAILED]
},
TEST_MALICIOUS_ACTIVITY_TIMELINE: {
TEST_EXPLANATION_KEY: u"The Monkeys in the network performed malicious-looking actions, like scanning and attempting exploitation.",
@ -80,22 +80,22 @@ TESTS_MAP = {
TEST_ENDPOINT_SECURITY_EXISTS: {
TEST_EXPLANATION_KEY: u"The Monkey checked if there is an active process of an endpoint security software.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_CONCLUSIVE: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus software on endpoints.",
STATUS_POSITIVE: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a security concern."
STATUS_FAILED: "Monkey didn't find ANY active endpoint security processes. Install and activate anti-virus software on endpoints.",
STATUS_PASSED: "Monkey found active endpoint security processes. Check their logs to see if Monkey was a security concern."
},
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
PILLARS_KEY: [DEVICES],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
},
TEST_MACHINE_EXPLOITED: {
TEST_EXPLANATION_KEY: u"The Monkey tries to exploit machines in order to breach them and propagate in the network.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_CONCLUSIVE: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see which endpoints were compromised.",
STATUS_POSITIVE: "Monkey didn't manage to exploit an endpoint."
STATUS_FAILED: "Monkey successfully exploited endpoints. Check IDS/IPS logs to see activity recognized and see which endpoints were compromised.",
STATUS_PASSED: "Monkey didn't manage to exploit an endpoint."
},
RECOMMENDATION_KEY: RECOMMENDATION_ENDPOINT_SECURITY,
PILLARS_KEY: [DEVICES],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_INCONCLUSIVE]
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_INCONCLUSIVE]
},
TEST_SCHEDULED_EXECUTION: {
TEST_EXPLANATION_KEY: "The Monkey was executed in a scheduled manner.",
@ -109,22 +109,22 @@ TESTS_MAP = {
TEST_DATA_ENDPOINT_ELASTIC: {
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to ElasticSearch instances.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_CONCLUSIVE: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.",
STATUS_POSITIVE: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts that indicate attempts to access them."
STATUS_FAILED: "Monkey accessed ElasticSearch instances. Limit access to data by encrypting it in in-transit.",
STATUS_PASSED: "Monkey didn't find open ElasticSearch instances. If you have such instances, look for alerts that indicate attempts to access them."
},
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
PILLARS_KEY: [DATA],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
},
TEST_DATA_ENDPOINT_HTTP: {
TEST_EXPLANATION_KEY: u"The Monkey scanned for unencrypted access to HTTP servers.",
FINDING_EXPLANATION_BY_STATUS_KEY: {
STATUS_CONCLUSIVE: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.",
STATUS_POSITIVE: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate attempts to access them."
STATUS_FAILED: "Monkey accessed HTTP servers. Limit access to data by encrypting it in in-transit.",
STATUS_PASSED: "Monkey didn't find open HTTP servers. If you have such servers, look for alerts that indicate attempts to access them."
},
RECOMMENDATION_KEY: RECOMMENDATION_DATA_TRANSIT,
PILLARS_KEY: [DATA],
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_CONCLUSIVE, STATUS_POSITIVE]
POSSIBLE_STATUSES_KEY: [STATUS_UNEXECUTED, STATUS_FAILED, STATUS_PASSED]
},
}

View File

@ -16,12 +16,13 @@ class Finding(Document):
This model represents a Zero-Trust finding: A result of a test the monkey/island might perform to see if a
specific recommendation of zero trust is upheld or broken.
Findings might be
Negative
Conclusive, meaning that we are sure that something is wrong (example: segmentation issue).
Inconclusive, meaning that we need the user to check something himself (example: 2FA logs, AV missing).
Positive
Conclusive, meaning that we are sure that something is correct (example: Monkey failed exploiting).
Findings might have the following statuses:
Failed
Meaning that we are sure that something is wrong (example: segmentation issue).
Inconclusive
Meaning that we need the user to check something himself (example: 2FA logs, AV missing).
Passed
Meaning that we are sure that something is correct (example: Monkey failed exploiting).
This class has 2 main section:
* The schema section defines the DB fields in the document. This is the data of the object.

View File

@ -1,30 +1,34 @@
from mongoengine import StringField
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_CONCLUSIVE, STATUS_POSITIVE
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_FAILED, STATUS_PASSED
from monkey_island.cc.models.zero_trust.finding import Finding
def need_to_overwrite_status(saved_status, new_status):
return (saved_status == STATUS_POSITIVE) and (new_status == STATUS_CONCLUSIVE)
return (saved_status == STATUS_PASSED) and (new_status == STATUS_FAILED)
class SegmentationFinding(Finding):
"""
trying to add conclusive:
If the finding doesn't exist at all: create conclusive
else:
if positive, turn to conclusive
add event
trying to add positive:
If the finding doesn't exist at all: create positive
else: add event
"""
first_subnet = StringField()
second_subnet = StringField()
@staticmethod
def create_or_add_to_existing_finding(subnets, status, segmentation_event):
"""
If you're trying to add a Failed finding:
If the finding doesn't exist at all: create failed
else:
if pass, turn to fail
add event
If you're trying to add a Passed finding:
If the finding doesn't exist at all: create Passed
else: add event
:param subnets: the 2 subnets of this finding.
:param status: STATUS_PASSED or STATUS_FAILED
:param segmentation_event: The specific event
"""
assert len(subnets) == 2
# Sort them so A -> B and B -> A segmentation findings will be the same one.

View File

@ -19,7 +19,7 @@ class TestFinding(IslandTestCase):
self.clean_finding_db()
with self.assertRaises(ValidationError):
_ = Finding.save_finding(test="bla bla", status=STATUS_CONCLUSIVE, events=[])
_ = Finding.save_finding(test="bla bla", status=STATUS_FAILED, events=[])
with self.assertRaises(ValidationError):
_ = Finding.save_finding(test=TEST_SEGMENTATION, status="bla bla", events=[])
@ -32,7 +32,7 @@ class TestFinding(IslandTestCase):
event_example = Event.create_event(
title="Event Title", message="event message", event_type=EVENT_TYPE_MONKEY_NETWORK)
Finding.save_finding(test=TEST_SEGMENTATION, status=STATUS_CONCLUSIVE, events=[event_example])
Finding.save_finding(test=TEST_SEGMENTATION, status=STATUS_FAILED, events=[event_example])
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 1)
self.assertEquals(len(Finding.objects(status=STATUS_CONCLUSIVE)), 1)
self.assertEquals(len(Finding.objects(status=STATUS_FAILED)), 1)

View File

@ -1,4 +1,4 @@
from common.data.zero_trust_consts import STATUS_CONCLUSIVE, EVENT_TYPE_MONKEY_NETWORK
from common.data.zero_trust_consts import STATUS_FAILED, EVENT_TYPE_MONKEY_NETWORK
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
from monkey_island.cc.models.zero_trust.segmentation_finding import SegmentationFinding
@ -16,7 +16,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding(
subnets=[first_segment, second_segment],
status=STATUS_CONCLUSIVE,
status=STATUS_FAILED,
segmentation_event=event
)
@ -26,7 +26,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER
subnets=[second_segment, first_segment],
status=STATUS_CONCLUSIVE,
status=STATUS_FAILED,
segmentation_event=event
)
@ -36,7 +36,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER
subnets=[first_segment, third_segment],
status=STATUS_CONCLUSIVE,
status=STATUS_FAILED,
segmentation_event=event
)
@ -45,7 +45,7 @@ class TestSegmentationFinding(IslandTestCase):
SegmentationFinding.create_or_add_to_existing_finding(
# !!! REVERSE ORDER
subnets=[second_segment, third_segment],
status=STATUS_CONCLUSIVE,
status=STATUS_FAILED,
segmentation_event=event
)

View File

@ -1,4 +1,4 @@
{
"server_config": "testing",
"server_config": "standard",
"deployment": "develop"
}

View File

@ -7,9 +7,9 @@ from monkey_island.cc.testing.IslandTestCase import IslandTestCase
def save_example_findings():
# arrange
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_POSITIVE, []) # devices positive = 1
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_POSITIVE, []) # devices positive = 2
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_CONCLUSIVE, []) # devices conclusive = 1
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED, []) # devices passed = 1
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_PASSED, []) # devices passed = 2
Finding.save_finding(TEST_ENDPOINT_SECURITY_EXISTS, STATUS_FAILED, []) # devices failed = 1
# devices unexecuted = 1
# people inconclusive = 1
# networks inconclusive = 1
@ -17,22 +17,22 @@ def save_example_findings():
# people inconclusive = 2
# networks inconclusive = 2
Finding.save_finding(TEST_SCHEDULED_EXECUTION, STATUS_INCONCLUSIVE, [])
# data conclusive 1
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
# data conclusive 2
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
# data conclusive 3
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
# data conclusive 4
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
# data conclusive 5
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_CONCLUSIVE, [])
# data failed 1
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
# data failed 2
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
# data failed 3
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
# data failed 4
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
# data failed 5
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_FAILED, [])
# data inconclusive 1
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
# data inconclusive 2
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_INCONCLUSIVE, [])
# data positive 1
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_POSITIVE, [])
# data passed 1
Finding.save_finding(TEST_DATA_ENDPOINT_HTTP, STATUS_PASSED, [])
class TestZeroTrustService(IslandTestCase):
@ -44,52 +44,52 @@ class TestZeroTrustService(IslandTestCase):
expected = [
{
"Conclusive": 5,
"Inconclusive": 2,
"Positive": 1,
"Unexecuted": 1,
STATUS_FAILED: 5,
STATUS_INCONCLUSIVE: 2,
STATUS_PASSED: 1,
STATUS_UNEXECUTED: 1,
"pillar": "Data"
},
{
"Conclusive": 0,
"Inconclusive": 2,
"Positive": 0,
"Unexecuted": 0,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 2,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 0,
"pillar": "People"
},
{
"Conclusive": 0,
"Inconclusive": 2,
"Positive": 0,
"Unexecuted": 2,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 2,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 2,
"pillar": "Networks"
},
{
"Conclusive": 1,
"Inconclusive": 0,
"Positive": 2,
"Unexecuted": 1,
STATUS_FAILED: 1,
STATUS_INCONCLUSIVE: 0,
STATUS_PASSED: 2,
STATUS_UNEXECUTED: 1,
"pillar": "Devices"
},
{
"Conclusive": 0,
"Inconclusive": 0,
"Positive": 0,
"Unexecuted": 0,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 0,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 0,
"pillar": "Workloads"
},
{
"Conclusive": 0,
"Inconclusive": 0,
"Positive": 0,
"Unexecuted": 1,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 0,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 1,
"pillar": "Visibility & Analytics"
},
{
"Conclusive": 0,
"Inconclusive": 0,
"Positive": 0,
"Unexecuted": 0,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 0,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 0,
"pillar": "Automation & Orchestration"
}
]
@ -109,14 +109,14 @@ class TestZeroTrustService(IslandTestCase):
DATA: [
{
"recommendation": RECOMMENDATIONS[RECOMMENDATION_DATA_TRANSIT],
"status": STATUS_CONCLUSIVE,
"status": STATUS_FAILED,
"tests": [
{
"status": STATUS_UNEXECUTED,
"test": TESTS_MAP[TEST_DATA_ENDPOINT_ELASTIC][TEST_EXPLANATION_KEY]
},
{
"status": STATUS_CONCLUSIVE,
"status": STATUS_FAILED,
"test": TESTS_MAP[TEST_DATA_ENDPOINT_HTTP][TEST_EXPLANATION_KEY]
}
]
@ -125,10 +125,10 @@ class TestZeroTrustService(IslandTestCase):
DEVICES: [
{
"recommendation": RECOMMENDATIONS[RECOMMENDATION_ENDPOINT_SECURITY],
"status": STATUS_CONCLUSIVE,
"status": STATUS_FAILED,
"tests": [
{
"status": STATUS_CONCLUSIVE,
"status": STATUS_FAILED,
"test": TESTS_MAP[TEST_ENDPOINT_SECURITY_EXISTS][TEST_EXPLANATION_KEY]
},
{
@ -221,12 +221,12 @@ class TestZeroTrustService(IslandTestCase):
expected = {
AUTOMATION_ORCHESTRATION: STATUS_UNEXECUTED,
DEVICES: STATUS_CONCLUSIVE,
DEVICES: STATUS_FAILED,
NETWORKS: STATUS_INCONCLUSIVE,
PEOPLE: STATUS_INCONCLUSIVE,
VISIBILITY_ANALYTICS: STATUS_UNEXECUTED,
WORKLOADS: STATUS_UNEXECUTED,
DATA: STATUS_CONCLUSIVE
DATA: STATUS_FAILED
}
self.assertEquals(ZeroTrustService.get_pillars_to_statuses(), expected)

View File

@ -16,9 +16,9 @@ class ZeroTrustService(object):
all_findings = Finding.objects()
pillar_grade = {
"pillar": pillar,
STATUS_CONCLUSIVE: 0,
STATUS_FAILED: 0,
STATUS_INCONCLUSIVE: 0,
STATUS_POSITIVE: 0,
STATUS_PASSED: 0,
STATUS_UNEXECUTED: 0
}
@ -123,9 +123,9 @@ class ZeroTrustService(object):
@staticmethod
def get_statuses_to_pillars():
results = {
STATUS_CONCLUSIVE: [],
STATUS_FAILED: [],
STATUS_INCONCLUSIVE: [],
STATUS_POSITIVE: [],
STATUS_PASSED: [],
STATUS_UNEXECUTED: []
}
for pillar in PILLARS:

View File

@ -1,6 +1,6 @@
from monkey_island.cc.services.node import NodeService
from monkey_island.cc.services.telemetry.zero_trust_tests.segmentation import \
test_positive_findings_for_unreached_segments
test_passed_findings_for_unreached_segments
def process_state_telemetry(telemetry_json):
@ -12,4 +12,4 @@ def process_state_telemetry(telemetry_json):
NodeService.set_monkey_dead(monkey, False)
if telemetry_json['data']['done']:
test_positive_findings_for_unreached_segments(telemetry_json)
test_passed_findings_for_unreached_segments(telemetry_json)

View File

@ -1,7 +1,7 @@
import json
from common.data.zero_trust_consts import EVENT_TYPE_MONKEY_LOCAL, EVENT_TYPE_ISLAND, \
STATUS_POSITIVE, STATUS_CONCLUSIVE, TEST_ENDPOINT_SECURITY_EXISTS
STATUS_PASSED, STATUS_FAILED, TEST_ENDPOINT_SECURITY_EXISTS
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.event import Event
from monkey_island.cc.models.zero_trust.finding import Finding
@ -28,9 +28,9 @@ def test_antivirus_existence(telemetry_json):
))
if len(av_processes) > 0:
test_status = STATUS_POSITIVE
test_status = STATUS_PASSED
else:
test_status = STATUS_CONCLUSIVE
test_status = STATUS_FAILED
Finding.save_finding(test=TEST_ENDPOINT_SECURITY_EXISTS, status=test_status, events=events)

View File

@ -11,8 +11,8 @@ HTTP_SERVERS_SERVICES_NAMES = ['tcp-80']
def test_open_data_endpoints(telemetry_json):
services = telemetry_json["data"]["machine"]["services"]
current_monkey = Monkey.get_single_monkey_by_guid(telemetry_json['monkey_guid'])
found_http_server_status = STATUS_POSITIVE
found_elastic_search_server = STATUS_POSITIVE
found_http_server_status = STATUS_PASSED
found_elastic_search_server = STATUS_PASSED
events = [
Event.create_event(
@ -32,7 +32,7 @@ def test_open_data_endpoints(telemetry_json):
event_type=EVENT_TYPE_ISLAND
))
if service_name in HTTP_SERVERS_SERVICES_NAMES:
found_http_server_status = STATUS_CONCLUSIVE
found_http_server_status = STATUS_FAILED
events.append(Event.create_event(
title="Scan telemetry analysis",
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(
@ -43,7 +43,7 @@ def test_open_data_endpoints(telemetry_json):
event_type=EVENT_TYPE_ISLAND
))
if service_name in 'elastic-search-9200':
found_elastic_search_server = STATUS_CONCLUSIVE
found_elastic_search_server = STATUS_FAILED
events.append(Event.create_event(
title="Scan telemetry analysis",
message="Service {} on {} recognized as an open data endpoint! Service details: {}".format(

View File

@ -18,7 +18,7 @@ def test_machine_exploited(telemetry_json):
)
]
status = STATUS_POSITIVE
status = STATUS_PASSED
if telemetry_json['data']['result']:
events.append(
@ -31,7 +31,7 @@ def test_machine_exploited(telemetry_json):
event_type=EVENT_TYPE_MONKEY_NETWORK,
timestamp=telemetry_json['timestamp'])
)
status = STATUS_CONCLUSIVE
status = STATUS_FAILED
Finding.save_finding(
test=TEST_MACHINE_EXPLOITED,

View File

@ -1,7 +1,7 @@
import itertools
from six import text_type
from common.data.zero_trust_consts import STATUS_CONCLUSIVE, EVENT_TYPE_MONKEY_NETWORK, STATUS_POSITIVE, \
from common.data.zero_trust_consts import STATUS_FAILED, EVENT_TYPE_MONKEY_NETWORK, STATUS_PASSED, \
EVENT_TYPE_ISLAND
from common.network.network_range import NetworkRange
from common.network.segmentation_utils import get_ip_in_src_and_not_in_dst, get_ip_if_in_subnet
@ -45,7 +45,7 @@ def test_segmentation_violation(scan_telemetry_json):
event = get_segmentation_violation_event(current_monkey, source_subnet, target_ip, target_subnet)
SegmentationFinding.create_or_add_to_existing_finding(
subnets=[source_subnet, target_subnet],
status=STATUS_CONCLUSIVE,
status=STATUS_FAILED,
segmentation_event=event
)
@ -64,7 +64,7 @@ def get_segmentation_violation_event(current_monkey, source_subnet, target_ip, t
)
def test_positive_findings_for_unreached_segments(state_telemetry_json):
def test_passed_findings_for_unreached_segments(state_telemetry_json):
flat_all_subnets = [item for sublist in get_config_network_segments_as_subnet_groups() for item in sublist]
current_monkey = Monkey.get_single_monkey_by_guid(state_telemetry_json['monkey_guid'])
create_or_add_findings_for_all_pairs(flat_all_subnets, current_monkey)
@ -87,7 +87,7 @@ def create_or_add_findings_for_all_pairs(all_subnets, current_monkey):
for subnet_pair in all_subnets_pairs_for_this_monkey:
SegmentationFinding.create_or_add_to_existing_finding(
subnets=list(subnet_pair),
status=STATUS_POSITIVE,
status=STATUS_PASSED,
segmentation_event=Event.create_event(
"Segmentation test done",
message="Monkey on {hostname} is done attempting cross-segment communications from `{src_seg}` "

View File

@ -1,6 +1,6 @@
import uuid
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_POSITIVE, STATUS_CONCLUSIVE, \
from common.data.zero_trust_consts import TEST_SEGMENTATION, STATUS_PASSED, STATUS_FAILED, \
EVENT_TYPE_MONKEY_NETWORK
from monkey_island.cc.models import Monkey
from monkey_island.cc.models.zero_trust.event import Event
@ -32,20 +32,15 @@ class TestSegmentationTests(IslandTestCase):
create_or_add_findings_for_all_pairs(all_subnets, monkey)
# There are 2 subnets in which the monkey is NOT
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_POSITIVE)), 2)
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_PASSED)), 2)
# This is a monkey from 2nd subnet communicated with 1st subnet.
SegmentationFinding.create_or_add_to_existing_finding(
[FIRST_SUBNET, SECOND_SUBNET],
STATUS_CONCLUSIVE,
STATUS_FAILED,
Event.create_event(title="sdf", message="asd", event_type=EVENT_TYPE_MONKEY_NETWORK)
)
print("Printing all segmentation findings")
all_findings = Finding.objects(test=TEST_SEGMENTATION)
for f in all_findings:
print(f.to_json())
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_POSITIVE)), 1)
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_CONCLUSIVE)), 1)
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_PASSED)), 1)
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION, status=STATUS_FAILED)), 1)
self.assertEquals(len(Finding.objects(test=TEST_SEGMENTATION)), 2)

View File

@ -12,6 +12,7 @@ import StatusesToPillarsSummary from "../report-components/zerotrust/StatusesToP
import PrintReportButton from "../report-components/common/PrintReportButton";
import {extractExecutionStatusFromServerResponse} from "../report-components/common/ExecutionStatus";
import ZeroTrustReportLegend from "../report-components/zerotrust/ReportLegend";
import {ZeroTrustStatuses} from "../report-components/zerotrust/ZeroTrustPillars";
class ZeroTrustReportPageComponent extends AuthComponent {
@ -179,14 +180,6 @@ class ZeroTrustReportPageComponent extends AuthComponent {
});
});
}
anyIssuesFound() {
const severe = function(finding) {
return (finding.status === "Conclusive" || finding.status === "Inconclusive");
};
return this.state.findings.some(severe);
}
}
export default ZeroTrustReportPageComponent;

View File

@ -1,27 +1,11 @@
import React, {Component} from "react";
import PillarLabel from "./PillarLabel";
import * as PropTypes from "prop-types";
import ResponsiveVennDiagram from "./venn-components/ResponsiveVennDiagram";
const columns = [
{
Header: 'Pillar Grading',
columns: [
{ Header: 'Pillar', id: 'Pillar', accessor: x => {
return (<PillarLabel pillar={x.pillar.name} status={x.pillar.status} />);
}},
{ Header: 'Conclusive', accessor: 'Conclusive'},
{ Header: 'Inconclusive', accessor: 'Inconclusive'},
{ Header: 'Unexecuted', accessor: 'Unexecuted'},
{ Header: 'Positive', accessor: 'Positive'},
]
}
];
class PillarOverview extends Component {
render() {
return (<div id={this.constructor.name}>
<ResponsiveVennDiagram pillarsGrades={this.props.grades} />
<ResponsiveVennDiagram pillarsGrades={this.props.grades}/>
</div>);
}
}

View File

@ -4,6 +4,7 @@ import AuthComponent from "../../AuthComponent";
import 'styles/ZeroTrustPillars.css'
import StatusLabel from "./StatusLabel";
import * as PropTypes from "prop-types";
import {ZeroTrustStatuses} from "./ZeroTrustPillars";
const columns = [
@ -30,17 +31,12 @@ const columns = [
class TestsStatus extends AuthComponent {
render() {
const positiveStatus = "Positive";
const conclusiveStatus = "Conclusive";
const inconclusiveStatus = "Inconclusive";
const unexecutedStatus = "Unexecuted";
return (
<Fragment>
{this.getFilteredTestsByStatusIfAny(conclusiveStatus)}
{this.getFilteredTestsByStatusIfAny(inconclusiveStatus)}
{this.getFilteredTestsByStatusIfAny(positiveStatus)}
{this.getFilteredTestsByStatusIfAny(unexecutedStatus)}
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.failed)}
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.inconclusive)}
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.passed)}
{this.getFilteredTestsByStatusIfAny(ZeroTrustStatuses.unexecuted)}
</Fragment>
);
}

View File

@ -38,7 +38,7 @@ class ZeroTrustReportLegend extends Component {
<ul style={{listStyle: "none"}}>
<li>
<div style={{display: "inline-block"}}>
<StatusLabel showText={true} status={ZeroTrustStatuses.conclusive}/>
<StatusLabel showText={true} status={ZeroTrustStatuses.failed}/>
</div>
{"\t"}The test failed; the monkeys found something wrong.
</li>
@ -50,7 +50,7 @@ class ZeroTrustReportLegend extends Component {
</li>
<li>
<div style={{display: "inline-block"}}>
<StatusLabel showText={true} status={ZeroTrustStatuses.positive}/>
<StatusLabel showText={true} status={ZeroTrustStatuses.passed}/>
</div>
{"\t"}This status means the test passed 🙂
</li>

View File

@ -2,16 +2,16 @@ import React, {Component} from "react";
import * as PropTypes from "prop-types";
const statusToIcon = {
"Positive": "fa-check",
"Passed": "fa-check",
"Inconclusive": "fa-exclamation-triangle",
"Conclusive": "fa-bomb",
"Failed": "fa-bomb",
"Unexecuted": "fa-question",
};
export const statusToLabelType = {
"Positive": "label-success",
"Passed": "label-success",
"Inconclusive": "label-warning",
"Conclusive": "label-danger",
"Failed": "label-danger",
"Unexecuted": "label-default",
};

View File

@ -2,14 +2,15 @@ import React, {Component, Fragment} from "react";
import PillarLabel from "./PillarLabel";
import StatusLabel from "./StatusLabel";
import * as PropTypes from "prop-types";
import {ZeroTrustStatuses} from "./ZeroTrustPillars";
export default class StatusesToPillarsSummary extends Component {
render() {
return (<div id="piilar-summary">
{this.getStatusSummary("Conclusive")}
{this.getStatusSummary("Inconclusive")}
{this.getStatusSummary("Positive")}
{this.getStatusSummary("Unexecuted")}
{this.getStatusSummary(ZeroTrustStatuses.failed)}
{this.getStatusSummary(ZeroTrustStatuses.inconclusive)}
{this.getStatusSummary(ZeroTrustStatuses.passed)}
{this.getStatusSummary(ZeroTrustStatuses.unexecuted)}
</div>);
}

View File

@ -9,9 +9,9 @@ export const ZeroTrustPillars = {
};
export const ZeroTrustStatuses = {
conclusive: "Conclusive",
failed: "Failed",
inconclusive: "Inconclusive",
positive: "Positive",
passed: "Passed",
unexecuted: "Unexecuted"
};

View File

@ -4,6 +4,7 @@ import CircularNode from './CircularNode'
import ArcNode from './ArcNode'
import {TypographicUtilities} from './Utility.js'
import './VennDiagram.css'
import {ZeroTrustStatuses} from "../ZeroTrustPillars";
class VennDiagram extends React.Component {
constructor(props_) {
@ -14,7 +15,7 @@ class VennDiagram extends React.Component {
this.width = this.height = 512;
this.prefix = 'vennDiagram';
this.suffices = ['', '|tests are|conclusive', '|tests were|inconclusive', '|tests|performed'];
this.suffices = ['', '|tests are|failed', '|tests were|inconclusive', '|tests|performed'];
this.fontStyles = [{size: Math.max(9, this.width / 32), color: 'white'}, {
size: Math.max(6, this.width / 52),
color: 'black'
@ -65,23 +66,23 @@ class VennDiagram extends React.Component {
this.rules = [
{
id: 'Rule #1', status: 'Unexecuted', hex: '#777777', f: function (d_) {
return d_['Conclusive'] + d_['Inconclusive'] + d_['Positive'] === 0;
id: 'Rule #1', status: ZeroTrustStatuses.unexecuted, hex: '#777777', f: function (d_) {
return d_[ZeroTrustStatuses.failed] + d_[ZeroTrustStatuses.inconclusive] + d_[ZeroTrustStatuses.passed] === 0;
}
},
{
id: 'Rule #2', status: 'Conclusive', hex: '#D9534F', f: function (d_) {
return d_['Conclusive'] > 0;
id: 'Rule #2', status: ZeroTrustStatuses.failed, hex: '#D9534F', f: function (d_) {
return d_[ZeroTrustStatuses.failed] > 0;
}
},
{
id: 'Rule #3', status: 'Inconclusive', hex: '#F0AD4E', f: function (d_) {
return d_['Conclusive'] === 0 && d_['Inconclusive'] > 0;
return d_[ZeroTrustStatuses.failed] === 0 && d_['Inconclusive'] > 0;
}
},
{
id: 'Rule #4', status: 'Positive', hex: '#5CB85C', f: function (d_) {
return d_['Positive'] + d_['Unexecuted'] >= 2 && d_['Positive'] * d_['Unexecuted'] > 0;
id: 'Rule #4', status: ZeroTrustStatuses.passed, hex: '#5CB85C', f: function (d_) {
return d_[ZeroTrustStatuses.passed] + d_[ZeroTrustStatuses.unexecuted] >= 2 && d_[ZeroTrustStatuses.passed] * d_[ZeroTrustStatuses.unexecuted] > 0;
}
}