From 22105eabe3d76096c5b6f65f23dd53e7a4976683 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Sun, 15 Oct 2017 20:06:26 +0300
Subject: [PATCH 01/62] Add basic report logic
---
monkey_island/cc/app.py | 3 +-
monkey_island/cc/resources/report.py | 10 +++++++
monkey_island/cc/services/report.py | 41 ++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 1 deletion(-)
create mode 100644 monkey_island/cc/resources/report.py
create mode 100644 monkey_island/cc/services/report.py
diff --git a/monkey_island/cc/app.py b/monkey_island/cc/app.py
index 6cfea1502..70001521a 100644
--- a/monkey_island/cc/app.py
+++ b/monkey_island/cc/app.py
@@ -15,7 +15,7 @@ from cc.resources.monkey_download import MonkeyDownload
from cc.resources.netmap import NetMap
from cc.resources.edge import Edge
from cc.resources.node import Node
-
+from cc.resources.report import Report
from cc.resources.root import Root
from cc.services.config import ConfigService
@@ -88,5 +88,6 @@ def init_app(mongo_url):
api.add_resource(NetMap, '/api/netmap', '/api/netmap/')
api.add_resource(Edge, '/api/netmap/edge', '/api/netmap/edge/')
api.add_resource(Node, '/api/netmap/node', '/api/netmap/node/')
+ api.add_resource(Report, '/api/report', '/api/report/')
return app
diff --git a/monkey_island/cc/resources/report.py b/monkey_island/cc/resources/report.py
new file mode 100644
index 000000000..e967b207f
--- /dev/null
+++ b/monkey_island/cc/resources/report.py
@@ -0,0 +1,10 @@
+import flask_restful
+
+from cc.services.report import ReportService
+
+__author__ = "itay.mizeretz"
+
+
+class Report(flask_restful.Resource):
+ def get(self):
+ return ReportService.get_report()
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
new file mode 100644
index 000000000..4356c84fd
--- /dev/null
+++ b/monkey_island/cc/services/report.py
@@ -0,0 +1,41 @@
+from cc.database import mongo
+
+__author__ = "itay.mizeretz"
+
+
+class ReportService:
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def get_first_monkey_time():
+ return mongo.db.telemetry.find({}, {'timestamp': 1}).sort([('$natural', 1)]).limit(1)[0]['timestamp']
+
+ @staticmethod
+ def get_last_monkey_dead_time():
+ return mongo.db.telemetry.find({}, {'timestamp': 1}).sort([('$natural', -1)]).limit(1)[0]['timestamp']
+
+ @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
+ def get_report():
+ return \
+ {
+ 'first_monkey_time': ReportService.get_first_monkey_time(),
+ 'last_monkey_dead_time': ReportService.get_last_monkey_dead_time(),
+ 'breach_count': ReportService.get_breach_count(),
+ 'successful_exploit_types': ReportService.get_successful_exploit_types(),
+ }
+
+ @staticmethod
+ def did_exploit_type_succeed(exploit_type):
+ return mongo.db.edge.count(
+ {'exploits': {'$elemMatch': {'exploiter': exploit_type, 'result': True}}},
+ limit=1) > 0
From 739edeff2a95defdafed49c3bdd07dd4407d4e77 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Mon, 16 Oct 2017 10:40:07 +0300
Subject: [PATCH 02/62] Add option to debug server
---
monkey_island/cc/island_config.py | 3 ++-
monkey_island/cc/main.py | 20 ++++++++++++--------
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/monkey_island/cc/island_config.py b/monkey_island/cc/island_config.py
index c53d27004..0a8f33bac 100644
--- a/monkey_island/cc/island_config.py
+++ b/monkey_island/cc/island_config.py
@@ -1,4 +1,5 @@
__author__ = 'itay.mizeretz'
ISLAND_PORT = 5000
-DEFAULT_MONGO_URL = "mongodb://localhost:27017/monkeyisland"
\ No newline at end of file
+DEFAULT_MONGO_URL = "mongodb://localhost:27017/monkeyisland"
+DEBUG_SERVER = False
diff --git a/monkey_island/cc/main.py b/monkey_island/cc/main.py
index dd133cfd1..68fae4e72 100644
--- a/monkey_island/cc/main.py
+++ b/monkey_island/cc/main.py
@@ -9,7 +9,7 @@ if BASE_PATH not in sys.path:
from cc.app import init_app
from cc.utils import local_ip_addresses
-from cc.island_config import DEFAULT_MONGO_URL, ISLAND_PORT
+from cc.island_config import DEFAULT_MONGO_URL, ISLAND_PORT, DEBUG_SERVER
if __name__ == '__main__':
from tornado.wsgi import WSGIContainer
@@ -17,10 +17,14 @@ if __name__ == '__main__':
from tornado.ioloop import IOLoop
app = init_app(os.environ.get('MONGO_URL', DEFAULT_MONGO_URL))
- http_server = HTTPServer(WSGIContainer(app),
- ssl_options={'certfile': os.environ.get('SERVER_CRT', 'server.crt'),
- 'keyfile': os.environ.get('SERVER_KEY', 'server.key')})
- http_server.listen(ISLAND_PORT)
- print('Monkey Island C&C Server is running on https://{}:{}'.format(local_ip_addresses()[0], ISLAND_PORT))
- IOLoop.instance().start()
- # app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key'))
+
+ if DEBUG_SERVER:
+ app.run(host='0.0.0.0', debug=True, ssl_context=('server.crt', 'server.key'))
+ else:
+ http_server = HTTPServer(WSGIContainer(app),
+ ssl_options={'certfile': os.environ.get('SERVER_CRT', 'server.crt'),
+ 'keyfile': os.environ.get('SERVER_KEY', 'server.key')})
+ http_server.listen(ISLAND_PORT)
+ print('Monkey Island C&C Server is running on https://{}:{}'.format(local_ip_addresses()[0], ISLAND_PORT))
+ IOLoop.instance().start()
+
From e9b6b39a2177761756d96f828884aa962a459695 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 7 Nov 2017 13:17:02 +0200
Subject: [PATCH 03/62] Add tunnel info to report
---
monkey_island/cc/services/node.py | 4 ++++
monkey_island/cc/services/report.py | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py
index 3acd66b75..af92eaa42 100644
--- a/monkey_island/cc/services/node.py
+++ b/monkey_island/cc/services/node.py
@@ -89,6 +89,10 @@ class NodeService:
return True
+ @staticmethod
+ def get_monkey_label_by_id(monkey_id):
+ return NodeService.get_monkey_label(NodeService.get_monkey_by_id(monkey_id))
+
@staticmethod
def get_monkey_label(monkey):
label = monkey["hostname"] + " : " + monkey["ip_addresses"][0]
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 4356c84fd..fd8bc3bdb 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -1,4 +1,5 @@
from cc.database import mongo
+from cc.services.node import NodeService
__author__ = "itay.mizeretz"
@@ -24,6 +25,12 @@ class ReportService:
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
+ def get_tunnels():
+ return [
+ (NodeService.get_monkey_label_by_id(tunnel['_id']), NodeService.get_monkey_label_by_id(tunnel['tunnel']))
+ for tunnel in mongo.db.monkey.find({'tunnel': {'$exists': True}}, {'tunnel': 1})]
+
@staticmethod
def get_report():
return \
@@ -32,6 +39,7 @@ class ReportService:
'last_monkey_dead_time': ReportService.get_last_monkey_dead_time(),
'breach_count': ReportService.get_breach_count(),
'successful_exploit_types': ReportService.get_successful_exploit_types(),
+ 'tunnels': ReportService.get_tunnels()
}
@staticmethod
From 8d9068fe40025f597c710e892bb69e0c0d994584 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 7 Nov 2017 14:52:13 +0200
Subject: [PATCH 04/62] Add known credentials to monkey documents
---
monkey_island/cc/resources/monkey.py | 3 +++
monkey_island/cc/resources/telemetry.py | 11 +++++++++++
monkey_island/cc/services/node.py | 15 +++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/monkey_island/cc/resources/monkey.py b/monkey_island/cc/resources/monkey.py
index 2e2da8a5d..0c6a8ddf1 100644
--- a/monkey_island/cc/resources/monkey.py
+++ b/monkey_island/cc/resources/monkey.py
@@ -53,6 +53,7 @@ class Monkey(flask_restful.Resource):
def post(self, **kw):
monkey_json = json.loads(request.data)
+ monkey_json['creds'] = {}
if 'keepalive' in monkey_json:
monkey_json['keepalive'] = dateutil.parser.parse(monkey_json['keepalive'])
else:
@@ -119,6 +120,8 @@ class Monkey(flask_restful.Resource):
node_id = existing_node["_id"]
for edge in mongo.db.edge.find({"to": node_id}):
mongo.db.edge.update({"_id": edge["_id"]}, {"$set": {"to": new_monkey_id}})
+ for user in existing_node['creds']:
+ NodeService.add_credentials_to_monkey(new_monkey_id, user, existing_node['creds'][user])
mongo.db.node.remove({"_id": node_id})
return {"id": new_monkey_id}
diff --git a/monkey_island/cc/resources/telemetry.py b/monkey_island/cc/resources/telemetry.py
index 88b144333..6df6649fa 100644
--- a/monkey_island/cc/resources/telemetry.py
+++ b/monkey_island/cc/resources/telemetry.py
@@ -115,6 +115,15 @@ class Telemetry(flask_restful.Resource):
if new_exploit['result']:
EdgeService.set_edge_exploited(edge)
+ for attempt in telemetry_json['data']['attempts']:
+ if attempt['result']:
+ attempt.pop('result')
+ user = attempt.pop('user')
+ for field in ['password', 'lm_hash', 'ntlm_hash']:
+ if len(attempt[field]) == 0:
+ attempt.pop(field)
+ NodeService.add_credentials_to_node(edge['to'], user, attempt)
+
@staticmethod
def process_scan_telemetry(telemetry_json):
edge = Telemetry.get_edge_by_scan_or_exploit_telemetry(telemetry_json)
@@ -151,6 +160,8 @@ class Telemetry(flask_restful.Resource):
creds = telemetry_json['data']['credentials']
for user in creds:
ConfigService.creds_add_username(user)
+ NodeService.add_credentials_to_monkey(
+ NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'], user, creds[user])
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])
if 'lm_hash' in creds[user]:
diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py
index af92eaa42..5777bcc36 100644
--- a/monkey_island/cc/services/node.py
+++ b/monkey_island/cc/services/node.py
@@ -170,6 +170,7 @@ class NodeService:
{
"ip_addresses": [ip_address],
"exploited": False,
+ "creds": {},
"os":
{
"type": "unknown",
@@ -277,3 +278,17 @@ class NodeService:
@staticmethod
def is_any_monkey_exists():
return mongo.db.monkey.find_one({}) is not None
+
+ @staticmethod
+ def add_credentials_to_monkey(monkey_id, user, creds):
+ mongo.db.monkey.update(
+ {'_id': monkey_id},
+ {'$set': {'creds.' + user: creds}}
+ )
+
+ @staticmethod
+ def add_credentials_to_node(node_id, user, creds):
+ mongo.db.node.update(
+ {'_id': node_id},
+ {'$set': {'creds.' + user: creds}}
+ )
From b284467fbcadeeec4bfe3d50936d98cd6ed42ce7 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 7 Nov 2017 16:33:26 +0200
Subject: [PATCH 05/62] Add scanned and exploited to report
---
monkey_island/cc/services/report.py | 38 ++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index fd8bc3bdb..ca7a55234 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -31,6 +31,40 @@ class ReportService:
(NodeService.get_monkey_label_by_id(tunnel['_id']), NodeService.get_monkey_label_by_id(tunnel['tunnel']))
for tunnel in mongo.db.monkey.find({'tunnel': {'$exists': True}}, {'tunnel': 1})]
+ @staticmethod
+ def get_scanned():
+ nodes =\
+ [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})]
+ nodes = [
+ {
+ 'label': node['label'],
+ 'ip_addresses': node['ip_addresses'],
+ 'accessible_from_nodes': node['accessible_from_nodes'],
+ 'services': node['services']
+ }
+ for node in nodes]
+
+ return nodes
+
+ @staticmethod
+ def get_exploited():
+ exploited =\
+ [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']))]\
+ + [NodeService.get_displayed_node_by_id(node['_id'])
+ for node in mongo.db.node.find({'exploited': True}, {'_id': 1})]
+
+ exploited = [
+ {
+ 'label': monkey['label'],
+ 'ip_addresses': monkey['ip_addresses'],
+ 'exploits': [exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]
+ }
+ for monkey in exploited]
+
+ return exploited
+
@staticmethod
def get_report():
return \
@@ -39,7 +73,9 @@ class ReportService:
'last_monkey_dead_time': ReportService.get_last_monkey_dead_time(),
'breach_count': ReportService.get_breach_count(),
'successful_exploit_types': ReportService.get_successful_exploit_types(),
- 'tunnels': ReportService.get_tunnels()
+ 'tunnels': ReportService.get_tunnels(),
+ 'scanned': ReportService.get_scanned(),
+ 'exploited': ReportService.get_exploited()
}
@staticmethod
From be8d20b2f5559f3bf7cb12ba8b02f664d2cfdd0a Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 7 Nov 2017 17:02:45 +0200
Subject: [PATCH 06/62] Change creds format in monkey document
---
monkey_island/cc/resources/monkey.py | 6 +++---
monkey_island/cc/resources/telemetry.py | 6 +++---
monkey_island/cc/services/node.py | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/monkey_island/cc/resources/monkey.py b/monkey_island/cc/resources/monkey.py
index 0c6a8ddf1..93fb0a0be 100644
--- a/monkey_island/cc/resources/monkey.py
+++ b/monkey_island/cc/resources/monkey.py
@@ -53,7 +53,7 @@ class Monkey(flask_restful.Resource):
def post(self, **kw):
monkey_json = json.loads(request.data)
- monkey_json['creds'] = {}
+ monkey_json['creds'] = []
if 'keepalive' in monkey_json:
monkey_json['keepalive'] = dateutil.parser.parse(monkey_json['keepalive'])
else:
@@ -120,8 +120,8 @@ class Monkey(flask_restful.Resource):
node_id = existing_node["_id"]
for edge in mongo.db.edge.find({"to": node_id}):
mongo.db.edge.update({"_id": edge["_id"]}, {"$set": {"to": new_monkey_id}})
- for user in existing_node['creds']:
- NodeService.add_credentials_to_monkey(new_monkey_id, user, existing_node['creds'][user])
+ for creds in existing_node['creds']:
+ NodeService.add_credentials_to_monkey(new_monkey_id, creds)
mongo.db.node.remove({"_id": node_id})
return {"id": new_monkey_id}
diff --git a/monkey_island/cc/resources/telemetry.py b/monkey_island/cc/resources/telemetry.py
index 6df6649fa..8698cd45f 100644
--- a/monkey_island/cc/resources/telemetry.py
+++ b/monkey_island/cc/resources/telemetry.py
@@ -118,11 +118,10 @@ class Telemetry(flask_restful.Resource):
for attempt in telemetry_json['data']['attempts']:
if attempt['result']:
attempt.pop('result')
- user = attempt.pop('user')
for field in ['password', 'lm_hash', 'ntlm_hash']:
if len(attempt[field]) == 0:
attempt.pop(field)
- NodeService.add_credentials_to_node(edge['to'], user, attempt)
+ NodeService.add_credentials_to_node(edge['to'], attempt)
@staticmethod
def process_scan_telemetry(telemetry_json):
@@ -160,8 +159,9 @@ class Telemetry(flask_restful.Resource):
creds = telemetry_json['data']['credentials']
for user in creds:
ConfigService.creds_add_username(user)
+ creds[user]['user'] = user
NodeService.add_credentials_to_monkey(
- NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'], user, creds[user])
+ NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'], creds[user])
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])
if 'lm_hash' in creds[user]:
diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py
index 5777bcc36..dc30d60d5 100644
--- a/monkey_island/cc/services/node.py
+++ b/monkey_island/cc/services/node.py
@@ -170,7 +170,7 @@ class NodeService:
{
"ip_addresses": [ip_address],
"exploited": False,
- "creds": {},
+ "creds": [],
"os":
{
"type": "unknown",
@@ -280,15 +280,15 @@ class NodeService:
return mongo.db.monkey.find_one({}) is not None
@staticmethod
- def add_credentials_to_monkey(monkey_id, user, creds):
+ def add_credentials_to_monkey(monkey_id, creds):
mongo.db.monkey.update(
{'_id': monkey_id},
- {'$set': {'creds.' + user: creds}}
+ {'$push': {'creds': creds}}
)
@staticmethod
- def add_credentials_to_node(node_id, user, creds):
+ def add_credentials_to_node(node_id, creds):
mongo.db.node.update(
{'_id': node_id},
- {'$set': {'creds.' + user: creds}}
+ {'$push': {'creds': creds}}
)
From be8feeb3ee124083895b2bb57c4b54711c2ca9b4 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Sun, 12 Nov 2017 16:11:12 +0200
Subject: [PATCH 07/62] Add get config value function
---
monkey_island/cc/services/config.py | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/monkey_island/cc/services/config.py b/monkey_island/cc/services/config.py
index 200e24029..2145011c3 100644
--- a/monkey_island/cc/services/config.py
+++ b/monkey_island/cc/services/config.py
@@ -806,6 +806,14 @@ class ConfigService:
config.pop(field, None)
return config
+ @staticmethod
+ def get_config_value(config_key_as_arr):
+ config_key = reduce(lambda x, y: x+'.'+y, config_key_as_arr)
+ config = mongo.db.config.find_one({'name': 'newconfig'}, {config_key: 1})
+ for config_key_part in config_key_as_arr:
+ config = config[config_key_part]
+ return config
+
@staticmethod
def get_flat_config():
config_json = ConfigService.get_config()
From 80b709b2ac8805a8fbc640725f118b6a9d7747d6 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Sun, 12 Nov 2017 16:13:40 +0200
Subject: [PATCH 08/62] Add reused passwords
---
monkey_island/cc/services/report.py | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index ca7a55234..0e0a2779f 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -1,4 +1,5 @@
from cc.database import mongo
+from cc.services.config import ConfigService
from cc.services.node import NodeService
__author__ = "itay.mizeretz"
@@ -47,6 +48,17 @@ class ReportService:
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
def get_exploited():
exploited =\
@@ -75,7 +87,8 @@ class ReportService:
'successful_exploit_types': ReportService.get_successful_exploit_types(),
'tunnels': ReportService.get_tunnels(),
'scanned': ReportService.get_scanned(),
- 'exploited': ReportService.get_exploited()
+ 'exploited': ReportService.get_exploited(),
+ 'reused_passwords': ReportService.get_reused_passwords()
}
@staticmethod
From 545b49919d483cec0f4444dcca8d62eb855ce1b5 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Sun, 12 Nov 2017 16:20:15 +0200
Subject: [PATCH 09/62] Remove mimikatz's stolen credentials from machine's
list of stolen creds
---
monkey_island/cc/resources/telemetry.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/monkey_island/cc/resources/telemetry.py b/monkey_island/cc/resources/telemetry.py
index 8698cd45f..666bfc16c 100644
--- a/monkey_island/cc/resources/telemetry.py
+++ b/monkey_island/cc/resources/telemetry.py
@@ -160,8 +160,6 @@ class Telemetry(flask_restful.Resource):
for user in creds:
ConfigService.creds_add_username(user)
creds[user]['user'] = user
- NodeService.add_credentials_to_monkey(
- NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'], creds[user])
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])
if 'lm_hash' in creds[user]:
From 0f2c58b0aa22f7be8e1579c99728256565792482 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Sun, 12 Nov 2017 20:52:01 +0200
Subject: [PATCH 10/62] Add skeleton and more of report
---
monkey_island/cc/ui/package.json | 1 +
monkey_island/cc/ui/src/components/Main.js | 1 +
.../cc/ui/src/components/pages/ReportPage.js | 106 +++++++++++++++++-
.../report-components/BreachedServers.js | 40 +++++++
.../report-components/ScannedServers.js | 41 +++++++
monkey_island/cc/ui/src/styles/App.css | 11 +-
6 files changed, 196 insertions(+), 4 deletions(-)
create mode 100644 monkey_island/cc/ui/src/components/report-components/BreachedServers.js
create mode 100644 monkey_island/cc/ui/src/components/report-components/ScannedServers.js
diff --git a/monkey_island/cc/ui/package.json b/monkey_island/cc/ui/package.json
index 681a98bb3..71f2decd4 100644
--- a/monkey_island/cc/ui/package.json
+++ b/monkey_island/cc/ui/package.json
@@ -80,6 +80,7 @@
"react-modal-dialog": "^4.0.7",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
+ "react-table": "^6.7.4",
"react-toggle": "^4.0.1",
"redux": "^3.7.2"
}
diff --git a/monkey_island/cc/ui/src/components/Main.js b/monkey_island/cc/ui/src/components/Main.js
index a4d41f2af..dd143ea3a 100644
--- a/monkey_island/cc/ui/src/components/Main.js
+++ b/monkey_island/cc/ui/src/components/Main.js
@@ -16,6 +16,7 @@ require('normalize.css/normalize.css');
require('react-data-components/css/table-twbs.css');
require('styles/App.css');
require('react-toggle/style.css');
+require('react-table/react-table.css');
let logoImage = require('../images/monkey-logo.png');
let guardicoreLogoImage = require('../images/guardicore-logo.png');
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 633fadc12..c568aa13b 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -1,19 +1,119 @@
import React from 'react';
import {Col} from 'react-bootstrap';
+import BreachedServers from 'components/report-components/BreachedServers';
+import ScannedServers from 'components/report-components/ScannedServers';
+
+const list_item = {
+ label: 'machine 1',
+ ip_addresses: ['1.2.3.4', '5.6.7.8'],
+ accessible_from_nodes: ['machine 2', 'machine 3'],
+ services: ['tcp-80', 'tcp-443']
+};
class ReportPageComponent extends React.Component {
constructor(props) {
super(props);
+
+ this.state = {
+ report: {}
+ };
+ }
+
+ componentDidMount() {
+ fetch('/api/report')
+ .then(res => res.json())
+ .then(res => {
+ this.setState({
+ report: res
+ });
+ });
}
render() {
+ if (Object.keys(this.state.report).length === 0) {
+ return ();
+ }
return (
4. Security Report
-
- Under construction
-
+
+
+ Overview
+
+
+ {/* TODO: Replace 01/02/2017 21:45, 23:12 with data */}
+ The monkey run was started on 01/02/2017 21:45. After 23:12 minutes, all monkeys finished propagation attempts.
+
+
+ From the attacker's point of view, the network looks like this:
+ {/* TODO: Add map */}
+
+
+
* Imagine Map here :) *
+
+
+ {/* TODO: Replace 3 with data */}
+ During this simulated attack the Monkey uncovered 3 issues, detailed below. The security issues uncovered included:
+
+ {/* TODO: Replace lis with data */}
+
Weak user/passwords combinations
+
Machines not patched for the ‘Shellshock’ bug
+
+
+
+ In addition, the monkey uncovered the following possible set of issues:
+
+ {/* TODO: Replace lis with data */}
+
Machines from another segment accessed the Monkey Island
+
Network tunnels were created successfully
+
+
+
+ A full report of the Monkeys activities follows.
+
+
+
+
+ Network Overview
+
+
+ {/* TODO: Replace 6,2 with data */}
+ During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
+ In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
+
+
+ Detailed recommendations in the next part of the report.
+
Breached Servers
+
+
+
+
Scanned Servers
+
+ {/* TODO: Add table of scanned servers */}
+
+
+
+
+ Recommendations
+
+
+
+
Issue #1
+
+ The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SmbExploiter attack.
+ The attack succeeded because weak/stolen password was used over SMB protocol.
+
+
+
+
Issue #2
+
+ The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
+
+ {/* TODO: Replace 01/02/2017 21:45, 23:12 with data */}
+ The monkey run was started on 01/02/2017 21:45. After 23:12 minutes, all monkeys finished propagation attempts.
+
+
+ From the attacker's point of view, the network looks like this:
+
+
+
+
+
+ {/* TODO: Replace 3 with data */}
+ During this simulated attack the Monkey uncovered 6 issues, detailed below. The security issues uncovered included:
+
+ {/* TODO: Replace lis with data */}
+
Weak user/passwords combinations.
+
Stolen passwords/hashes used to exploit other machines.
+
Elastic Search servers not patched for CVE-2015-1427 bug.
+
Samba servers not patched for ‘SambaCry’ bug.
+
Machines not patched for the ‘Shellshock’ bug.
+
Machines not patched for the ‘Conficker’ bug.
+
+
+
+ In addition, the monkey uncovered the following possible set of issues:
+
+ {/* TODO: Replace lis with data */}
+
Machines freely accessed the Monkey Island despite being on different networks.
+
Machines are not locked down at port level, tunnels between network segments were setup successfully.
+
+
+
+ A full report of the Monkeys activities follows.
+
+
+
+
+ Network Overview
+
+
+ {/* TODO: Replace 6,2 with data */}
+ During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
+ In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
+
+
+ Detailed recommendations in the next part of the report.
+
Breached Servers
+
+
+
+
Scanned Servers
+
+ {/* TODO: Add table of scanned servers */}
+
+
+
+
+ Stolen Credentials
+
+
+
+
+
+ Recommendations
+
+
+
+
Issue #1
+
+ The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SMB attack.
+
+ The attack succeeded by authenticating over SMB protocol with user Administrator and its password.
+
+
+
+
Issue #2
+
+ The machine Monkey-SMB2 with the following IP address 192.168.0.2 was vulnerable to a SMB attack.
+
+ The attack succeeded by using a pass-the-hash attack over SMB protocol with user temp.
+
+
+
+
Issue #3
+
+ The machine Monkey-WMI with the following IP address 192.168.0.3 was vulnerable to a WMI attack.
+
+ The attack succeeded by authenticating over WMI protocol with user Administrator and its password.
+
+
+
+
Issue #4
+
+ The machine Monkey-WMI2 with the following IP address 192.168.0.4 was vulnerable to a WMI attack.
+
+ The attack succeeded by using a pass-the-hash attack over WMI protocol with user Administrator.
+
+
+
+
Issue #5
+
+ The machine Monkey-SSH with the following IP address 192.168.0.5 was vulnerable to a SSH attack.
+
+ The attack succeeded by authenticating over SSH protocol with user user and its password.
+
+
+
+
Issue #6
+
+ The machine Monkey-RDP with the following IP address 192.168.0.6 was vulnerable to a RDP attack.
+
+ The attack succeeded by authenticating over RDP protocol with user Administrator and its password.
+
+
+
+
Issue #7
+
+ The machine Monkey-SambaCry with the following IP address 192.168.0.7 was vulnerable to a SambaCry attack.
+
+ The attack succeeded by authenticating over SMB protocol with user user and its password, and by using the SambaCry vulnerability.
+
+
+
+
Issue #8
+
+ The machine Monkey-Elastic with the following IP address 192.168.0.8 was vulnerable to an Elastic Groovy attack.
+
+ The attack succeeded because the Elastic Search server was not parched against the CVE-2015-1427 bug.
+
+
+
+
Issue #9
+
+ The machine Monkey-Shellshock with the following IP address 192.168.0.9 was vulnerable to a ShellShock attack.
+
+ The attack succeeded because the HTTP server running on port 8080 was vulnerable to a shell injection attack on the paths: /cgi/backserver.cgi/cgi/login.cgi.
+
+
+
+
Issue #10
+
+ The machine Monkey-Conficker with the following IP address 192.168.0.10 was vulnerable to a Conficker attack.
+
+ The attack succeeded because the target machine uses an outdated and unpatched operating system.
+
+
+
+
Issue #11
+
+ The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
+
+
+
+
Issue #12
+
+ The network can probably be segmented. A monkey instance on Monkey-SSH in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
+
+
+
+
Issue #13
+
+ Machines are not locked down at port level. Network tunnel was set up from Monkey-SSH to Monkey-SambaCry.
+
+
+
+
+
+ );
}
return (
4. Security Report
-
-
- Overview
-
-
- {/* TODO: Replace 01/02/2017 21:45, 23:12 with data */}
- The monkey run was started on 01/02/2017 21:45. After 23:12 minutes, all monkeys finished propagation attempts.
-
-
- From the attacker's point of view, the network looks like this:
-
-
-
-
-
- {/* TODO: Replace 3 with data */}
- During this simulated attack the Monkey uncovered 3 issues, detailed below. The security issues uncovered included:
-
- {/* TODO: Replace lis with data */}
-
Weak user/passwords combinations
-
Machines not patched for the ‘Shellshock’ bug
-
-
-
- In addition, the monkey uncovered the following possible set of issues:
-
- {/* TODO: Replace lis with data */}
-
Machines from another segment accessed the Monkey Island
-
Network tunnels were created successfully
-
-
-
- A full report of the Monkeys activities follows.
-
-
-
-
- Network Overview
-
-
- {/* TODO: Replace 6,2 with data */}
- During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
- In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
-
-
- Detailed recommendations in the next part of the report.
-
Breached Servers
-
-
-
-
Scanned Servers
-
- {/* TODO: Add table of scanned servers */}
-
-
-
-
- Recommendations
-
-
-
-
Issue #1
-
- The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SmbExploiter attack.
- The attack succeeded because weak/stolen password was used over SMB protocol.
-
-
-
-
Issue #2
-
- The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
-
- {/* TODO: Replace 6,2 with data */}
- During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
- In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
-
- Detailed recommendations in the next part of the report.
-
Breached Servers
+
+
+ {/* TODO: Replace 6,2 with data */}
+ During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
+
+ In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
+
+ Detailed recommendations in the next part of the report.
+
+ )
+ }
+}
+
+export default ScannedBreachedChartComponent;
diff --git a/monkey_island/cc/ui/src/components/report-components/ScannedServers.js b/monkey_island/cc/ui/src/components/report-components/ScannedServers.js
index 9ae1b5135..b598ab537 100644
--- a/monkey_island/cc/ui/src/components/report-components/ScannedServers.js
+++ b/monkey_island/cc/ui/src/components/report-components/ScannedServers.js
@@ -9,10 +9,15 @@ let renderArray = function(val) {
};
const columns = [
- { Header: 'Machine', accessor: 'label'},
- { Header: 'IP Addresses', id: 'ip_addresses', accessor: x => renderArray(x.ip_addresses)},
- { Header: 'Accessible From', id: 'accessible_from_nodes', accessor: x => renderArray(x.accessible_from_nodes)},
- { Header: 'Services', id: 'services', accessor: x => renderArray(x.services)}
+ {
+ Header: 'Scanned Servers',
+ columns: [
+ { Header: 'Machine', accessor: 'label'},
+ { Header: 'IP Addresses', id: 'ip_addresses', accessor: x => renderArray(x.ip_addresses)},
+ { Header: 'Accessible From', id: 'accessible_from_nodes', accessor: x => renderArray(x.accessible_from_nodes)},
+ { Header: 'Services', id: 'services', accessor: x => renderArray(x.services)}
+ ]
+ }
];
const pageSize = 10;
diff --git a/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js b/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
index c34d51bed..754b51f92 100644
--- a/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
+++ b/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
@@ -2,10 +2,15 @@ import React from 'react';
import ReactTable from 'react-table'
const columns = [
- { Header: 'Username', accessor: 'username'},
- { Header: 'Password/Hash', accessor: 'password'},
- { Header: 'Type', accessor: 'type'},
- { Header: 'Origin', accessor: 'origin'}
+ {
+ Header: 'Stolen Credentials',
+ columns: [
+ { Header: 'Username', accessor: 'username'},
+ { Header: 'Password/Hash', accessor: 'password'},
+ { Header: 'Type', accessor: 'type'},
+ { Header: 'Origin', accessor: 'origin'}
+ ]
+ }
];
const pageSize = 10;
From f787801ab7b922157bb7455f66a512e6f6c94c8d Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 14 Nov 2017 16:10:22 +0200
Subject: [PATCH 14/62] Add recommendations to security issues
---
.../cc/ui/src/components/pages/ReportPage.js | 68 ++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 1bf41a2e8..6bdb62fbc 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -146,6 +146,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SMB attack.
The attack succeeded by authenticating over SMB protocol with user Administrator and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -154,6 +159,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-SMB2 with the following IP address 192.168.0.2 was vulnerable to a SMB attack.
The attack succeeded by using a pass-the-hash attack over SMB protocol with user temp.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -162,6 +172,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-WMI with the following IP address 192.168.0.3 was vulnerable to a WMI attack.
The attack succeeded by authenticating over WMI protocol with user Administrator and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -170,6 +185,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-WMI2 with the following IP address 192.168.0.4 was vulnerable to a WMI attack.
The attack succeeded by using a pass-the-hash attack over WMI protocol with user Administrator.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -178,6 +198,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-SSH with the following IP address 192.168.0.5 was vulnerable to a SSH attack.
The attack succeeded by authenticating over SSH protocol with user user and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -186,6 +211,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-RDP with the following IP address 192.168.0.6 was vulnerable to a RDP attack.
The attack succeeded by authenticating over RDP protocol with user Administrator and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -194,6 +224,12 @@ class ReportPageComponent extends React.Component {
The machine Monkey-SambaCry with the following IP address 192.168.0.7 was vulnerable to a SambaCry attack.
The attack succeeded by authenticating over SMB protocol with user user and its password, and by using the SambaCry vulnerability.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
+
Use a complex one-use password that is not shared with other computers on the network.
+
@@ -202,6 +238,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-Elastic with the following IP address 192.168.0.8 was vulnerable to an Elastic Groovy attack.
The attack succeeded because the Elastic Search server was not parched against the CVE-2015-1427 bug.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Update your Elastic Search server to version 1.4.3 and up.
+
@@ -210,6 +251,11 @@ class ReportPageComponent extends React.Component {
The machine Monkey-Shellshock with the following IP address 192.168.0.9 was vulnerable to a ShellShock attack.
The attack succeeded because the HTTP server running on port 8080 was vulnerable to a shell injection attack on the paths: /cgi/backserver.cgi/cgi/login.cgi.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Update your Bash to a ShellShock-patched version.
+
@@ -217,25 +263,45 @@ class ReportPageComponent extends React.Component {
The machine Monkey-Conficker with the following IP address 192.168.0.10 was vulnerable to a Conficker attack.
- The attack succeeded because the target machine uses an outdated and unpatched operating system.
+ The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Install the latest Windows updates or upgrade to a newer operating system.
+
Issue #11
The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
+
+ In order to protect the network, the following steps should be performed:
+
+
Segment your network. Make sure machines can't access machines from other segments.
+
Issue #12
The network can probably be segmented. A monkey instance on Monkey-SSH in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
+
+ In order to protect the network, the following steps should be performed:
+
+
Segment your network. Make sure machines can't access machines from other segments.
+
Issue #13
Machines are not locked down at port level. Network tunnel was set up from Monkey-SSH to Monkey-SambaCry.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use micro-segmentation policies to disable communication other than the required.
{/* TODO: Replace 3 with data */}
- During this simulated attack the Monkey uncovered 6 issues, detailed below. The security issues uncovered included:
+ During this simulated attack the Monkey uncovered 6 issues, detailed below. The security issues uncovered include:
{/* TODO: Replace lis with data */}
-
Weak user/passwords combinations.
-
Stolen passwords/hashes used to exploit other machines.
-
Elastic Search servers not patched for CVE-2015-1427 bug.
-
Samba servers not patched for ‘SambaCry’ bug.
-
Machines not patched for the ‘Shellshock’ bug.
-
Machines not patched for the ‘Conficker’ bug.
+
Users with weak passwords.
+
Stolen passwords/hashes were used to exploit other machines.
+
Elastic Search servers not patched for CVE-2015-1427.
+
Samba servers not patched for ‘SambaCry’ (CVE-2017-7494).
+
Machines not patched for the ‘Shellshock’ (CVE-2014-6271).
+
Machines not patched for the ‘Conficker’ (MS08-067).
In addition, the monkey uncovered the following possible set of issues:
{/* TODO: Replace lis with data */}
-
Machines freely accessed the Monkey Island despite being on different networks.
-
Machines are not locked down at port level, tunnels between network segments were setup successfully.
+
Possible cross segment traffic. Infected machines could communicate with the Monkey Island despite crossing segment boundaries using unused ports.
+
Lack of port level segmentation, machines successfully tunneled monkey activity using unused ports.
@@ -111,9 +111,9 @@ class ReportPageComponent extends React.Component {
{/* TODO: Replace 6,2 with data */}
- During the current run, the Monkey discovered 6 machines and successfully breached 2 of them.
+ The Monkey discovered 6 machines and successfully breached 2 of them.
- In addition, it attempted to exploit the rest, any security software installed in the network should have picked up the attack attempts and logged them.
+ In addition, while attempting to exploit additional hosts , security software installed in the network should have picked up the attack attempts and logged them.
Detailed recommendations in the next part of the report.
@@ -142,7 +142,7 @@ class ReportPageComponent extends React.Component {
Issue #1
-
+
The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SMB attack.
The attack succeeded by authenticating over SMB protocol with user Administrator and its password.
@@ -151,11 +151,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #2
-
+
The machine Monkey-SMB2 with the following IP address 192.168.0.2 was vulnerable to a SMB attack.
The attack succeeded by using a pass-the-hash attack over SMB protocol with user temp.
@@ -164,11 +164,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #3
-
+
The machine Monkey-WMI with the following IP address 192.168.0.3 was vulnerable to a WMI attack.
The attack succeeded by authenticating over WMI protocol with user Administrator and its password.
@@ -177,11 +177,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #4
-
+
The machine Monkey-WMI2 with the following IP address 192.168.0.4 was vulnerable to a WMI attack.
The attack succeeded by using a pass-the-hash attack over WMI protocol with user Administrator.
@@ -190,11 +190,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #5
-
+
The machine Monkey-SSH with the following IP address 192.168.0.5 was vulnerable to a SSH attack.
The attack succeeded by authenticating over SSH protocol with user user and its password.
@@ -203,11 +203,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #6
-
+
The machine Monkey-RDP with the following IP address 192.168.0.6 was vulnerable to a RDP attack.
The attack succeeded by authenticating over RDP protocol with user Administrator and its password.
@@ -216,11 +216,11 @@ class ReportPageComponent extends React.Component {
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #7
-
+
The machine Monkey-SambaCry with the following IP address 192.168.0.7 was vulnerable to a SambaCry attack.
The attack succeeded by authenticating over SMB protocol with user user and its password, and by using the SambaCry vulnerability.
@@ -230,24 +230,24 @@ class ReportPageComponent extends React.Component {
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
Use a complex one-use password that is not shared with other computers on the network.
-
+
Issue #8
-
+
The machine Monkey-Elastic with the following IP address 192.168.0.8 was vulnerable to an Elastic Groovy attack.
- The attack succeeded because the Elastic Search server was not parched against the CVE-2015-1427 bug.
+ The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
In order to protect the machine, the following steps should be performed:
Update your Elastic Search server to version 1.4.3 and up.
-
+
Issue #9
-
+
The machine Monkey-Shellshock with the following IP address 192.168.0.9 was vulnerable to a ShellShock attack.
The attack succeeded because the HTTP server running on port 8080 was vulnerable to a shell injection attack on the paths: /cgi/backserver.cgi/cgi/login.cgi.
@@ -256,11 +256,11 @@ class ReportPageComponent extends React.Component {
Update your Bash to a ShellShock-patched version.
-
+
Issue #10
-
+
The machine Monkey-Conficker with the following IP address 192.168.0.10 was vulnerable to a Conficker attack.
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
@@ -269,40 +269,40 @@ class ReportPageComponent extends React.Component {
Install the latest Windows updates or upgrade to a newer operating system.
-
+
Issue #11
-
+
The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
In order to protect the network, the following steps should be performed:
Segment your network. Make sure machines can't access machines from other segments.
-
+
Issue #12
-
+
The network can probably be segmented. A monkey instance on Monkey-SSH in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
In order to protect the network, the following steps should be performed:
Segment your network. Make sure machines can't access machines from other segments.
-
+
Issue #13
-
+
Machines are not locked down at port level. Network tunnel was set up from Monkey-SSH to Monkey-SambaCry.
In order to protect the machine, the following steps should be performed:
Use micro-segmentation policies to disable communication other than the required.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SMB attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SMB attack.
+
+ The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a WMI attack.
+
+ The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a WMI attack.
+
+ The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SSH attack.
+
+ The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a RDP attack.
+
+ The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SambaCry attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry vulnerability.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
+
Use a complex one-use password that is not shared with other computers on the network.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to an Elastic Groovy attack.
+
+ The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Update your Elastic Search server to version 1.4.3 and up.
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a ShellShock attack.
+
+ The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
+
+ In order to protect the machine, the following steps should be performed:
+
+ The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a Conficker attack.
+
+ The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Install the latest Windows updates or upgrade to a newer operating system.
+ The network can probably be segmented. A monkey instance on {issue.machine} in the {issue.network} network could directly access the Monkey Island C&C server in the {issue.server_network} network.
+
+ In order to protect the network, the following steps should be performed:
+
+
Segment your network. Make sure machines can't access machines from other segments.
+ Machines are not locked down at port level. Network tunnel was set up from {issue.origin} to {issue.dest}.
+
+ In order to protect the machine, the following steps should be performed:
+
+
Use micro-segmentation policies to disable communication other than the required.
+
+
+ );
+ }
+
+ generateIssue = (issue, index) => {
+ let data;
+ switch (issue.type) {
+ case 'smb_password':
+ data = this.generateSmbPasswordIssue(issue);
+ break;
+ case 'smb_pth':
+ data = this.generateSmbPthIssue(issue);
+ break;
+ case 'wmi_password':
+ data = this.generateWmiPasswordIssue(issue);
+ break;
+ case 'wmi_pth':
+ data = this.generateWmiPthIssue(issue);
+ break;
+ case 'ssh':
+ data = this.generateSshIssue(issue);
+ break;
+ case 'rdp':
+ data = this.generateRdpIssue(issue);
+ break;
+ case 'sambacry':
+ data = this.generateSambaCryIssue(issue);
+ break;
+ case 'elastic':
+ data = this.generateElasticIssue(issue);
+ break;
+ case 'shellshock':
+ data = this.generateShellshockIssue(issue);
+ break;
+ case 'conficker':
+ data = this.generateConfickerIssue(issue);
+ break;
+ case 'cross_segment':
+ data = this.generateCrossSegmentIssue(issue);
+ break;
+ case 'tunnel':
+ data = this.generateTunnelIssue(issue);
+ break;
+ }
+ return (
+
- {/* TODO: Replace 01/02/2017 21:45, 23:12 with data */}
- The monkey run was started on 01/02/2017 21:45. After 23:12 minutes, all monkeys finished propagation attempts.
+ The monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished propagation attempts.
From the attacker's point of view, the network looks like this:
@@ -79,24 +363,21 @@ class ReportPageComponent extends React.Component {
- {/* TODO: Replace 3 with data */}
- During this simulated attack the Monkey uncovered 6 issues, detailed below. The security issues uncovered include:
+ During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function(x){return x===true;}).length}, detailed below. The security issues uncovered include:
- {/* TODO: Replace lis with data */}
-
Users with weak passwords.
-
Stolen passwords/hashes were used to exploit other machines.
-
Elastic Search servers not patched for CVE-2015-1427.
-
Samba servers not patched for ‘SambaCry’ (CVE-2017-7494).
-
Machines not patched for the ‘Shellshock’ (CVE-2014-6271).
-
Machines not patched for the ‘Conficker’ (MS08-067).
Lack of port level segmentation, machines successfully tunneled monkey activity using unused ports.
: null}
@@ -110,8 +391,7 @@ class ReportPageComponent extends React.Component {
- {/* TODO: Replace 6,2 with data */}
- The Monkey discovered 6 machines and successfully breached 2 of them.
+ The Monkey discovered {this.state.report.glance.scanned.length} machines and successfully breached {this.state.report.glance.exploited.length} of them.
In addition, while attempting to exploit additional hosts , security software installed in the network should have picked up the attack attempts and logged them.
@@ -120,191 +400,27 @@ class ReportPageComponent extends React.Component {
-
+
-
+
-
- {/* TODO: Add table of scanned servers */}
+
-
+
Recommendations
-
-
Issue #1
-
- The machine Monkey-SMB with the following IP addresses 192.168.0.110.0.0.18 was vulnerable to a SMB attack.
-
- The attack succeeded by authenticating over SMB protocol with user Administrator and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
- The machine Monkey-SMB2 with the following IP address 192.168.0.2 was vulnerable to a SMB attack.
-
- The attack succeeded by using a pass-the-hash attack over SMB protocol with user temp.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #3
-
- The machine Monkey-WMI with the following IP address 192.168.0.3 was vulnerable to a WMI attack.
-
- The attack succeeded by authenticating over WMI protocol with user Administrator and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #4
-
- The machine Monkey-WMI2 with the following IP address 192.168.0.4 was vulnerable to a WMI attack.
-
- The attack succeeded by using a pass-the-hash attack over WMI protocol with user Administrator.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #5
-
- The machine Monkey-SSH with the following IP address 192.168.0.5 was vulnerable to a SSH attack.
-
- The attack succeeded by authenticating over SSH protocol with user user and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #6
-
- The machine Monkey-RDP with the following IP address 192.168.0.6 was vulnerable to a RDP attack.
-
- The attack succeeded by authenticating over RDP protocol with user Administrator and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #7
-
- The machine Monkey-SambaCry with the following IP address 192.168.0.7 was vulnerable to a SambaCry attack.
-
- The attack succeeded by authenticating over SMB protocol with user user and its password, and by using the SambaCry vulnerability.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
-
Use a complex one-use password that is not shared with other computers on the network.
-
-
-
-
-
Issue #8
-
- The machine Monkey-Elastic with the following IP address 192.168.0.8 was vulnerable to an Elastic Groovy attack.
-
- The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Elastic Search server to version 1.4.3 and up.
-
-
-
-
-
Issue #9
-
- The machine Monkey-Shellshock with the following IP address 192.168.0.9 was vulnerable to a ShellShock attack.
-
- The attack succeeded because the HTTP server running on port 8080 was vulnerable to a shell injection attack on the paths: /cgi/backserver.cgi/cgi/login.cgi.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Bash to a ShellShock-patched version.
-
-
-
-
-
Issue #10
-
- The machine Monkey-Conficker with the following IP address 192.168.0.10 was vulnerable to a Conficker attack.
-
- The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
-
- In order to protect the machine, the following steps should be performed:
-
-
Install the latest Windows updates or upgrade to a newer operating system.
-
-
-
-
-
Issue #11
-
- The network can probably be segmented. A monkey instance on Monkey-SMB in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
-
- In order to protect the network, the following steps should be performed:
-
-
Segment your network. Make sure machines can't access machines from other segments.
-
-
-
-
-
Issue #12
-
- The network can probably be segmented. A monkey instance on Monkey-SSH in the 192.168.0.0/24 network could directly access the Monkey Island C&C server in the 172.168.0.0/24 network.
-
- In order to protect the network, the following steps should be performed:
-
-
Segment your network. Make sure machines can't access machines from other segments.
-
-
-
-
-
Issue #13
-
- Machines are not locked down at port level. Network tunnel was set up from Monkey-SSH to Monkey-SambaCry.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use micro-segmentation policies to disable communication other than the required.
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SMB attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
@@ -91,7 +91,7 @@ class ReportPageComponent extends React.Component {
generateSmbPthIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SMB attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
@@ -106,7 +106,7 @@ class ReportPageComponent extends React.Component {
generateWmiPasswordIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a WMI attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
@@ -121,7 +121,7 @@ class ReportPageComponent extends React.Component {
generateWmiPthIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a WMI attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
@@ -136,7 +136,7 @@ class ReportPageComponent extends React.Component {
generateSshIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SSH attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SSH attack.
The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
@@ -151,7 +151,7 @@ class ReportPageComponent extends React.Component {
generateRdpIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a RDP attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a RDP attack.
The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
@@ -166,7 +166,7 @@ class ReportPageComponent extends React.Component {
generateSambaCryIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a SambaCry attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SambaCry attack.
The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry vulnerability.
@@ -182,7 +182,7 @@ class ReportPageComponent extends React.Component {
generateElasticIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to an Elastic Groovy attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to an Elastic Groovy attack.
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
@@ -197,7 +197,7 @@ class ReportPageComponent extends React.Component {
generateShellshockIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a ShellShock attack.
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a ShellShock attack.
The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
@@ -212,7 +212,7 @@ class ReportPageComponent extends React.Component {
generateConfickerIssue(issue) {
return (
- The machine {issue.machine} with the following IP addresses {this.generateIpListBadges(issue.ip_addresses)} was vulnerable to a Conficker attack.
+ The machine {issue.machine} with the following address {issue.ip_address} was vulnerable to a Conficker attack.
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
@@ -227,7 +227,7 @@ class ReportPageComponent extends React.Component {
generateCrossSegmentIssue(issue) {
return (
- The network can probably be segmented. A monkey instance on {issue.machine} in the {issue.network} network could directly access the Monkey Island C&C server in the {issue.server_network} network.
+ The network can probably be segmented. A monkey instance on {issue.machine} in the networks {this.generateInfoBadges(issue.networks)} could directly access the Monkey Island C&C server in the networks {this.generateInfoBadges(issue.server_networks)}.
In order to protect the network, the following steps should be performed:
diff --git a/monkey_island/cc/utils.py b/monkey_island/cc/utils.py
index 34026b157..d59c23825 100644
--- a/monkey_island/cc/utils.py
+++ b/monkey_island/cc/utils.py
@@ -4,6 +4,7 @@ import sys
import array
import struct
+import ipaddress
from netifaces import interfaces, ifaddresses, AF_INET
from cc.database import mongo
@@ -56,3 +57,11 @@ def local_ip_addresses():
addresses = ifaddresses(interface).get(AF_INET, [])
ip_list.extend([link['addr'] for link in addresses if link['addr'] != '127.0.0.1'])
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
diff --git a/monkey_island/requirements.txt b/monkey_island/requirements.txt
index 275c8b96a..1aa7288c5 100644
--- a/monkey_island/requirements.txt
+++ b/monkey_island/requirements.txt
@@ -9,4 +9,5 @@ flask
Flask-Pymongo
Flask-Restful
jsonschema
-netifaces
\ No newline at end of file
+netifaces
+ipaddress
\ No newline at end of file
From f72b32bb671abcadf2c2b60dc2527fa084ce8560 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Mon, 27 Nov 2017 15:51:56 +0200
Subject: [PATCH 23/62] Removed duplicate issues
---
monkey_island/cc/services/report.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 609b17c31..30cdf14ec 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -208,8 +208,12 @@ class ReportService:
@staticmethod
def get_exploits():
- return [ReportService.process_exploit(exploit) for
- exploit in mongo.db.telemetry.find({'telem_type': 'exploit', 'data.result': True})]
+ exploits = []
+ for exploit in mongo.db.telemetry.find({'telem_type': 'exploit', 'data.result': True}):
+ new_exploit = ReportService.process_exploit(exploit)
+ if new_exploit not in exploits:
+ exploits.append(new_exploit)
+ return exploits
@staticmethod
def get_monkey_subnets(monkey_guid):
From 4f6ed955017d4ce1cc6565064fbc90fb542e984b Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 13:40:51 +0200
Subject: [PATCH 24/62] Fix bug with exploited nodes
---
monkey_island/cc/services/report.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 30cdf14ec..3a3509a40 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -78,7 +78,7 @@ class ReportService:
exploited = [
{
- 'label': NodeService.get_node_hostname(monkey),
+ 'label': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_id(monkey['id'])),
'ip_addresses': monkey['ip_addresses'],
'exploits': [exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]
}
From 2aadb1281555d7a6a76be824c4a266153c853a0b Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 14:16:16 +0200
Subject: [PATCH 25/62] Change page structure
---
.../cc/ui/src/components/pages/ReportPage.js | 49 ++++++++++++-------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 305d39fd6..be5c0e9e3 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -311,16 +311,21 @@ class ReportPageComponent extends React.Component {
Overview
- The monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished propagation attempts.
+ The first monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished propagation attempts.
- From the attacker's point of view, the network looks like this:
+ A full report of the Monkeys activities follows.
-
-
-
+
+
+
+ Security Findings
+
- During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function(x){return x===true;}).length}, detailed below. The security issues uncovered include:
+
+ Immediate Threats
+
+ During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function(x){return x===true;}).length} issues, detailed below. The security issues uncovered include:
- Machines are not locked down at port level. Network tunnel was set up from {issue.origin} to {issue.dest}.
+ Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
In order to protect the machine, the following steps should be performed:
From dff90ab5340f600e7e8c530252e9bbbbc8309d31 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 14:37:11 +0200
Subject: [PATCH 28/62] Remove duplicate exploits on breached servers
---
monkey_island/cc/services/report.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 867feeda6..5af051e72 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -80,7 +80,7 @@ class ReportService:
{
'label': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_id(monkey['id'])),
'ip_addresses': monkey['ip_addresses'],
- 'exploits': [exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]
+ 'exploits': list(set([exploit['exploiter'] for exploit in monkey['exploits'] if exploit['result']]))
}
for monkey in exploited]
From 96972aeac9c55266d835ba9fe1b30d9117821d85 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 14:47:54 +0200
Subject: [PATCH 29/62] Micro segmentation, not port level segmentation
---
monkey_island/cc/ui/src/components/pages/ReportPage.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 3966311f2..6c9c7cde3 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -342,7 +342,7 @@ class ReportPageComponent extends React.Component {
The monkey uncovered the following possible set of issues:
Lack of Micro-segmentation, machines successfully tunneled monkey activity using unused ports.
: null}
From da55b0b26ba0bbd5a4344fae90c0c7f53ab7fad1 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 17:11:00 +0200
Subject: [PATCH 30/62] Group recommendations by machine. Show recommendation
with collapsible incident
---
monkey_island/cc/services/report.py | 9 +-
.../cc/ui/src/components/pages/ReportPage.js | 229 ++++++++++--------
.../report-components/CollapsibleWell.js | 30 +++
3 files changed, 168 insertions(+), 100 deletions(-)
create mode 100644 monkey_island/cc/ui/src/components/report-components/CollapsibleWell.js
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 5af051e72..01205e71a 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -252,8 +252,13 @@ class ReportService:
@staticmethod
def get_issues():
issues = ReportService.get_exploits() + ReportService.get_tunnels() + ReportService.get_cross_segment_issues()
- issues.sort(lambda x, y: 1 if x['machine'] > y['machine'] else -1 if x['machine'] < y['machine'] else 0)
- return issues
+ issues_dict = {}
+ for issue in issues:
+ machine = issue['machine']
+ if machine not in issues_dict:
+ issues_dict[machine] = []
+ issues_dict[machine].append(issue)
+ return issues_dict
@staticmethod
def get_report():
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 6c9c7cde3..24c666c68 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -6,6 +6,7 @@ import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
import {options, edgeGroupToColor} from 'components/map/MapOptions';
import StolenPasswords from 'components/report-components/StolenPasswords';
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
+import CollapsableWellComponent from "../report-components/CollapsibleWell";
class ReportPageComponent extends React.Component {
@@ -70,20 +71,22 @@ class ReportPageComponent extends React.Component {
}
generateShellshockPathListBadges(paths) {
- return paths.map(path => {path});
+ return paths.map(path => {path});
}
generateSmbPasswordIssue(issue) {
return (
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
-
- The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
-
- The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
+
+ The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
-
- The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
+
+ The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
-
- The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
+
+ The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SSH attack.
-
- The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SSH attack.
+
+ The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a RDP attack.
-
- The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a RDP attack.
+
+ The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SambaCry attack.
-
- The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry vulnerability.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
-
Use a complex one-use password that is not shared with other computers on the network.
-
+ Change {issue.username}'s password to a complex one-use password
+ that is not shared with other computers on the network.
+
+ Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SambaCry attack.
+
+ The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry
+ vulnerability.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to an Elastic Groovy attack.
-
- The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Elastic Search server to version 1.4.3 and up.
-
+ Update your Elastic Search server to version 1.4.3 and up.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to an Elastic Groovy attack.
+
+ The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
+
- The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a ShellShock attack.
-
- The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the paths: {this.generateShellshockPathListBadges(issue.paths)}.
-
- In order to protect the machine, the following steps should be performed:
-
-
Update your Bash to a ShellShock-patched version.
-
+ Update your Bash to a ShellShock-patched version.
+
+ The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a ShellShock attack.
+
+ The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the
+ paths: {this.generateShellshockPathListBadges(issue.paths)}.
+
- The machine {issue.machine} with the following address {issue.ip_address} was vulnerable to a Conficker attack.
-
- The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to Conficker.
-
- In order to protect the machine, the following steps should be performed:
-
-
Install the latest Windows updates or upgrade to a newer operating system.
-
+ Install the latest Windows updates or upgrade to a newer operating system.
+
+ The machine {issue.machine} with the following address {issue.ip_address} was vulnerable to a Conficker attack.
+
+ The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to
+ Conficker.
+
- The network can probably be segmented. A monkey instance on {issue.machine} in the networks {this.generateInfoBadges(issue.networks)} could directly access the Monkey Island C&C server in the networks {this.generateInfoBadges(issue.server_networks)}.
-
- In order to protect the network, the following steps should be performed:
-
-
Segment your network. Make sure machines can't access machines from other segments.
-
+ Segment your network. Make sure machines can't access machines from other segments.
+
+ The network can probably be segmented. A monkey instance on {issue.machine} in the
+ networks {this.generateInfoBadges(issue.networks)}
+ could directly access the Monkey Island C&C server in the
+ networks {this.generateInfoBadges(issue.server_networks)}.
+
- Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
-
- In order to protect the machine, the following steps should be performed:
-
-
Use micro-segmentation policies to disable communication other than the required.
-
+ Use micro-segmentation policies to disable communication other than the required.
+
+ Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
+
+ );
+ }
+}
+
+export default CollapsibleWellComponent;
From 881cf5e7931e08372131dc8d849f8409743641cd Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 17:12:48 +0200
Subject: [PATCH 31/62] Collapsible-Collapsable
---
.../cc/ui/src/components/pages/ReportPage.js | 50 +++++++++----------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 24c666c68..cea8c8d87 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -6,7 +6,7 @@ import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
import {options, edgeGroupToColor} from 'components/map/MapOptions';
import StolenPasswords from 'components/report-components/StolenPasswords';
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
-import CollapsableWellComponent from "../report-components/CollapsibleWell";
+import CollapsibleWellComponent from "../report-components/CollapsibleWell";
class ReportPageComponent extends React.Component {
@@ -79,14 +79,14 @@ class ReportPageComponent extends React.Component {
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SMB attack.
The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a WMI attack.
The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SSH attack.
The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a RDP attack.
The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
-
+
);
}
@@ -183,7 +183,7 @@ class ReportPageComponent extends React.Component {
that is not shared with other computers on the network.
Update your Samba server to 4.4.14 and up, 4.5.10 and up, or 4.6.4 and up.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a SambaCry attack.
@@ -191,7 +191,7 @@ class ReportPageComponent extends React.Component {
The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password, and by using the SambaCry
vulnerability.
-
+
Update your Elastic Search server to version 1.4.3 and up.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to an Elastic Groovy attack.
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
-
+
Update your Bash to a ShellShock-patched version.
-
+
The machine {issue.machine} with the following IP address {issue.ip_address} was vulnerable to a ShellShock attack.
@@ -223,7 +223,7 @@ class ReportPageComponent extends React.Component {
The attack succeeded because the HTTP server running on port {issue.port} was vulnerable to a shell injection attack on the
paths: {this.generateShellshockPathListBadges(issue.paths)}.
-
+
Install the latest Windows updates or upgrade to a newer operating system.
-
+
The machine {issue.machine} with the following address {issue.ip_address} was vulnerable to a Conficker attack.
The attack succeeded because the target machine uses an outdated and unpatched operating system vulnerable to
Conficker.
-
+
Segment your network. Make sure machines can't access machines from other segments.
-
+
The network can probably be segmented. A monkey instance on {issue.machine} in the
networks {this.generateInfoBadges(issue.networks)}
could directly access the Monkey Island C&C server in the
networks {this.generateInfoBadges(issue.server_networks)}.
-
+
Use micro-segmentation policies to disable communication other than the required.
-
+
Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
-
+
);
}
From 88ea57dc8874e88f9ffb664b2f1e9470d190fcec Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 28 Nov 2017 17:16:58 +0200
Subject: [PATCH 32/62] Fix most printing format issues Improve CSS Shorten
lines
---
.../cc/ui/src/components/pages/ReportPage.js | 81 +++++++++++++------
monkey_island/cc/ui/src/styles/App.css | 63 +++++++++++----
2 files changed, 104 insertions(+), 40 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index cea8c8d87..4e34dd3a8 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -3,10 +3,10 @@ import {Col} from 'react-bootstrap';
import BreachedServers from 'components/report-components/BreachedServers';
import ScannedServers from 'components/report-components/ScannedServers';
import {ReactiveGraph} from 'components/reactive-graph/ReactiveGraph';
-import {options, edgeGroupToColor} from 'components/map/MapOptions';
+import {edgeGroupToColor, options} from 'components/map/MapOptions';
import StolenPasswords from 'components/report-components/StolenPasswords';
import ScannedBreachedChart from 'components/report-components/ScannedBreachedChart';
-import CollapsibleWellComponent from "../report-components/CollapsibleWell";
+import CollapsibleWellComponent from 'components/report-components/CollapsibleWell';
class ReportPageComponent extends React.Component {
@@ -338,13 +338,16 @@ class ReportPageComponent extends React.Component {
} else {
content =
(
-
+
- Overview
+ Executive Summary
- The first monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished propagation attempts.
+ The first monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished
+ propagation attempts.
A full report of the Monkeys activities follows.
@@ -358,14 +361,31 @@ class ReportPageComponent extends React.Component {
Immediate Threats
- During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function(x){return x===true;}).length} issues, detailed below. The security issues uncovered include:
-
Lack of Micro-segmentation, machines successfully tunneled monkey activity
+ using unused ports.
: null}
@@ -394,33 +418,38 @@ class ReportPageComponent extends React.Component {
- The Monkey discovered {this.state.report.glance.scanned.length} machines and successfully breached {this.state.report.glance.exploited.length} of them.
-
- In addition, while attempting to exploit additional hosts , security software installed in the network should have picked up the attack attempts and logged them.
-
+ The Monkey discovered {this.state.report.glance.scanned.length} machines and
+ successfully breached {this.state.report.glance.exploited.length} of them.
+
+ In addition, while attempting to exploit additional hosts , security software installed in the
+ network should have picked up the attack attempts and logged them.
+
Detailed recommendations in the next part of the report.
-
+
From the attacker's point of view, the network looks like this:
@@ -416,25 +419,22 @@ class ReportPageComponent extends React.Component {
The Network from the Monkey's Eyes
-
-
- The Monkey discovered {this.state.report.glance.scanned.length} machines and
- successfully breached {this.state.report.glance.exploited.length} of them.
-
- In addition, while attempting to exploit additional hosts , security software installed in the
- network should have picked up the attack attempts and logged them.
-
- Detailed recommendations in the next part of the report.
-
-
-
-
-
-
-
+
+ The Monkey discovered {this.state.report.glance.scanned.length} machines and
+ successfully breached {this.state.report.glance.exploited.length} of them.
+
+ In addition, while attempting to exploit additional hosts , security software installed in the
+ network should have picked up the attack attempts and logged them.
+
+ Detailed recommendations in the next part of the report.
+
+
+
+ {Math.round(exploitPercentage)}% of machines exploited
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -87,13 +87,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by authenticating over SMB protocol with user {issue.username} and its password.
-
+
);
}
generateSmbPthIssue(issue) {
return (
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -104,13 +104,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by using a pass-the-hash attack over SMB protocol with user {issue.username}.
-
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -121,13 +121,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by authenticating over WMI protocol with user {issue.username} and its password.
-
+
);
}
generateWmiPthIssue(issue) {
return (
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -138,13 +138,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by using a pass-the-hash attack over WMI protocol with user {issue.username}.
-
+
);
}
generateSshIssue(issue) {
return (
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -155,13 +155,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by authenticating over SSH protocol with user {issue.username} and its password.
-
+
);
}
generateRdpIssue(issue) {
return (
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -172,13 +172,13 @@ class ReportPageComponent extends React.Component {
The attack succeeded by authenticating over RDP protocol with user {issue.username} and its password.
-
+
);
}
generateSambaCryIssue(issue) {
return (
-
+
Change {issue.username}'s password to a complex one-use password
that is not shared with other computers on the network.
@@ -192,13 +192,13 @@ class ReportPageComponent extends React.Component {
className="label label-success">{issue.username} and its password, and by using the SambaCry
vulnerability.
-
+
);
}
generateElasticIssue(issue) {
return (
-
+
Update your Elastic Search server to version 1.4.3 and up.
The machine {issue.machine} with the following IP address
The attack succeeded because the Elastic Search server was not parched against CVE-2015-1427.
-
Update your Bash to a ShellShock-patched version.
The machine {issue.machine} with the following IP address {issue.port} was vulnerable to a shell injection attack on the
paths: {this.generateShellshockPathListBadges(issue.paths)}.
-
+
);
}
generateConfickerIssue(issue) {
return (
-
+
Install the latest Windows updates or upgrade to a newer operating system.
The machine {issue.machine} with the following address
-
Segment your network. Make sure machines can't access machines from other segments.
The network can probably be segmented. A monkey instance on
-
+
);
}
generateTunnelIssue(issue) {
return (
-
+
Use micro-segmentation policies to disable communication other than the required.
Machines are not locked down at port level. Network tunnel was set up from {issue.machine} to {issue.dest}.
-
- The first monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished
- propagation attempts.
-
-
- A full report of the Monkeys activities follows.
-
+
+
+
-
-
- Security Findings
-
-
-
- Immediate Threats
-
- During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function (x) {
- return x === true;
- }).length} issues, detailed below. The security issues uncovered include:
-
- The Monkey discovered {this.state.report.glance.scanned.length} machines and
- successfully breached {this.state.report.glance.exploited.length} of them.
-
- In addition, while attempting to exploit additional hosts , security software installed in the
- network should have picked up the attack attempts and logged them.
-
- Detailed recommendations in the next part of the report.
+
+
+ Critical security issues found by Infection Monkey!
+
) :
+ (
+
+ Infection Monkey did not find any critical security issues.
+
)
+ }
+
+
+ To improve the monkey's success rate, try adding users and passwords, and enabling the "Local
+ network scan" config value under "Basic - Network"
-
-
- {Math.round(exploitPercentage)}% of scanned machines exploited
+
+ The first monkey run was started on {this.state.report.overview.monkey_start_time}. After {this.state.report.overview.monkey_duration}, all monkeys finished
+ propagation attempts.
+
+
+ The monkey started propagating from the following machines where it was manually installed:
+
+ The Monkey discovered {this.state.report.glance.scanned.length} machines and
+ successfully breached {this.state.report.glance.exploited.length} of them.
+
+ In addition, while attempting to exploit additional hosts , security software installed in the
+ network should have picked up the attack attempts and logged them.
+
+ Detailed recommendations in the next part of the report.
+
+
+
+ {Math.round(exploitPercentage)}% of scanned machines exploited
+
+
+
+ From the attacker's point of view, the network looks like this:
+
- To improve the monkey's success rate, try adding users and passwords, and enabling the "Local
- network scan" config value under "Basic - Network"
+ To improve the monkey's detection rates, try adding users and passwords and enable the "Local network
+ scan" config value under Basic - Network.
The first monkey run was started on 0 ?
- Use the following exploit methods:
+ Used the following exploit methods:
Elastic Search servers not patched for CVE-2015-1427.
diff --git a/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js b/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
index 7c42b6ea5..fde46f85a 100644
--- a/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
+++ b/monkey_island/cc/ui/src/components/report-components/StolenPasswords.js
@@ -7,7 +7,7 @@ const columns = [
columns: [
{ Header: 'Username', accessor: 'username'},
{ Header: 'Type', accessor: 'type'},
- { Header: 'Origin', accessor: 'origin'}
+ { Header: 'Stolen From', accessor: 'origin'}
]
}
];
From 2c8b510b0c16e42ab73b8f31e25c8c2dbf38ac86 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 12 Dec 2017 12:45:53 +0200
Subject: [PATCH 39/62] Exploits used are listed only if they're not the
default configuration. Suggestion to improve monkey success rate appears only
if no critical issues were found
---
monkey_island/cc/services/report.py | 11 ++++-
.../cc/ui/src/components/pages/ReportPage.js | 45 ++++++++++++++-----
2 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 048e2fb12..6b0e408ce 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -276,6 +276,15 @@ class ReportService:
@staticmethod
def get_config_exploits():
+ exploits_config_value = ['exploits', 'general', 'exploiter_classes']
+ default_exploits = ConfigService.get_default_config()
+ for namespace in exploits_config_value:
+ default_exploits = default_exploits[namespace]
+ exploits = ConfigService.get_config_value(exploits_config_value)
+
+ if exploits == default_exploits:
+ return ['default']
+
exploit_display_dict = \
{
'SmbExploiter': 'SMB Exploiter',
@@ -288,7 +297,7 @@ class ReportService:
'ShellShockExploiter': 'ShellShock Exploiter',
}
return [exploit_display_dict[exploit] for exploit in
- ConfigService.get_config_value(['exploits', 'general', 'exploiter_classes'])]
+ exploits]
@staticmethod
def get_config_ips():
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index f1daa6d3c..2a12587f6 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -330,7 +330,7 @@ class ReportPageComponent extends React.Component {
generateIssues = (issues) => {
let issuesDivArray = [];
- for (var machine of Object.keys(issues)) {
+ for (let machine of Object.keys(issues)) {
issuesDivArray.push(
{machine}
@@ -343,6 +343,17 @@ class ReportPageComponent extends React.Component {
return
{issuesDivArray}
;
};
+ didMonkeyFindIssues = () => {
+ for (let issue of Object.keys(this.state.report.overview.issues)) {
+ if (this.state.report.overview.issues[issue]) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+
+
render() {
let content;
if (Object.keys(this.state.report).length === 0) {
@@ -384,11 +395,16 @@ class ReportPageComponent extends React.Component {
running.
)
}
-
-
- To improve the monkey's detection rates, try adding users and passwords and enable the "Local network
- scan" config value under Basic - Network.
-
+ {
+ this.didMonkeyFindIssues() ?
+ ''
+ :
+
+
+ To improve the monkey's detection rates, try adding users and passwords and enable the "Local network
+ scan" config value under Basic - Network.
+
+ }
The first monkey run was started on {this.state.report.overview.monkey_start_time}. After 0 ?
-
- To improve the monkey's detection rates, try adding users and passwords and enable the "Local network
+ To improve the monkey's detection rates, try adding users and passwords and enable the "Local
+ network
scan" config value under Basic - Network.
+
+ You have to run a monkey before generating a report!
+
;
+ }
} else {
let exploitPercentage =
(100 * this.state.report.glance.exploited.length) / this.state.report.glance.scanned.length;
From f2b631745d34f389a52c5b0702b0c7e38a4cf54e Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 12 Dec 2017 15:45:32 +0200
Subject: [PATCH 44/62] Fix bug where stolen credentials had '.' in username
---
monkey_island/cc/resources/telemetry.py | 14 ++++++++++++--
monkey_island/cc/services/report.py | 15 +++++++++------
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/monkey_island/cc/resources/telemetry.py b/monkey_island/cc/resources/telemetry.py
index 666bfc16c..7b3a6e616 100644
--- a/monkey_island/cc/resources/telemetry.py
+++ b/monkey_island/cc/resources/telemetry.py
@@ -39,7 +39,6 @@ class Telemetry(flask_restful.Resource):
telemetry_json = json.loads(request.data)
telemetry_json['timestamp'] = datetime.now()
- telem_id = mongo.db.telemetry.insert(telemetry_json)
monkey = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])
try:
@@ -53,6 +52,7 @@ class Telemetry(flask_restful.Resource):
print("Exception caught while processing telemetry: %s" % str(ex))
traceback.print_exc()
+ telem_id = mongo.db.telemetry.insert(telemetry_json)
return mongo.db.telemetry.find_one_or_404({"_id": telem_id})
@staticmethod
@@ -70,6 +70,11 @@ class Telemetry(flask_restful.Resource):
monkey_label = telem_monkey_guid
x["monkey"] = monkey_label
objects.append(x)
+ if x['telem_type'] == 'system_info_collection' and 'credentials' in x['data']:
+ for user in x['data']['credentials']:
+ if -1 != user.find(','):
+ new_user = user.replace(',', '.')
+ x['data']['credentials'][new_user] = x['data']['credentials'].pop(user)
return objects
@@ -159,7 +164,6 @@ class Telemetry(flask_restful.Resource):
creds = telemetry_json['data']['credentials']
for user in creds:
ConfigService.creds_add_username(user)
- creds[user]['user'] = user
if 'password' in creds[user]:
ConfigService.creds_add_password(creds[user]['password'])
if 'lm_hash' in creds[user]:
@@ -167,11 +171,17 @@ class Telemetry(flask_restful.Resource):
if 'ntlm_hash' in creds[user]:
ConfigService.creds_add_ntlm_hash(creds[user]['ntlm_hash'])
+ for user in creds:
+ if -1 != user.find('.'):
+ new_user = user.replace('.', ',')
+ creds[new_user] = creds.pop(user)
+
@staticmethod
def process_trace_telemetry(telemetry_json):
# Nothing to do
return
+
TELEM_PROCESS_DICT = \
{
'tunnel': Telemetry.process_tunnel_telemetry,
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 8261b7e7b..ab6c9fb13 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -117,7 +117,7 @@ class ReportService:
for pass_type in monkey_creds[user]:
creds.append(
{
- 'username': user,
+ 'username': user.replace(',', '.'),
'type': PASS_TYPE_DICT[pass_type],
'origin': origin
}
@@ -231,14 +231,17 @@ class ReportService:
@staticmethod
def get_monkey_subnets(monkey_guid):
+ network_info = mongo.db.telemetry.find_one(
+ {'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid},
+ {'data.network_info.networks': 1}
+ )
+ if network_info is None:
+ return []
+
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']
+ for network in network_info['data']['network_info']['networks']
]
@staticmethod
From 434c72f69f808bf9f50e2988644762a05667ef91 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 12 Dec 2017 16:33:16 +0200
Subject: [PATCH 45/62] Implemented issues and warnings on overview
---
monkey_island/cc/services/report.py | 68 ++++++++++++--
.../cc/ui/src/components/pages/ReportPage.js | 94 ++++++++++++-------
2 files changed, 119 insertions(+), 43 deletions(-)
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index ab6c9fb13..4b3bf8573 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -25,6 +25,18 @@ class ReportService:
'ShellShockExploiter': 'ShellShock Exploiter',
}
+ class ISSUES_DICT:
+ WEAK_PASSWORD = 0
+ STOLEN_CREDS = 1
+ ELASTIC = 2
+ SAMBACRY = 3
+ SHELLSHOCK = 4
+ CONFICKER = 5
+
+ class WARNINGS_DICT:
+ CROSS_SEGMENT = 0
+ TUNNEL = 1
+
@staticmethod
def get_first_monkey_time():
return mongo.db.telemetry.find({}, {'timestamp': 1}).sort([('$natural', 1)]).limit(1)[0]['timestamp']
@@ -139,6 +151,7 @@ class ReportService:
processed_exploit['username'] = attempt['user']
if len(attempt['password']) > 0:
processed_exploit['type'] = 'password'
+ processed_exploit['password'] = attempt['password']
else:
processed_exploit['type'] = 'hash'
return processed_exploit
@@ -232,9 +245,9 @@ class ReportService:
@staticmethod
def get_monkey_subnets(monkey_guid):
network_info = mongo.db.telemetry.find_one(
- {'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid},
- {'data.network_info.networks': 1}
- )
+ {'telem_type': 'system_info_collection', 'monkey_guid': monkey_guid},
+ {'data.network_info.networks': 1}
+ )
if network_info is None:
return []
@@ -315,22 +328,61 @@ class ReportService:
def get_config_scan():
return ConfigService.get_config_value(['basic_network', 'general', 'local_network_scan'], True)
+ @staticmethod
+ def get_issues_overview(issues, config_users, config_passwords):
+ issues_byte_array = [False] * 6
+
+ for machine in issues:
+ for issue in issues[machine]:
+ if issue['type'] == 'elastic':
+ issues_byte_array[ReportService.ISSUES_DICT.ELASTIC] = True
+ elif issue['type'] == 'sambacry':
+ issues_byte_array[ReportService.ISSUES_DICT.SAMBACRY] = True
+ elif issue['type'] == 'shellshock':
+ issues_byte_array[ReportService.ISSUES_DICT.SHELLSHOCK] = True
+ elif issue['type'] == 'conficker':
+ issues_byte_array[ReportService.ISSUES_DICT.CONFICKER] = True
+ elif issue['type'].endswith('_password') and issue['password'] in config_passwords and \
+ issue['username'] in config_users:
+ issues_byte_array[ReportService.ISSUES_DICT.WEAK_PASSWORD] = True
+ elif issue['type'].endswith('_pth') or issue['type'].endswith('_password'):
+ issues_byte_array[ReportService.ISSUES_DICT.STOLEN_CREDS] = True
+
+ return issues_byte_array
+
+ @staticmethod
+ def get_warnings_overview(issues):
+ warnings_byte_array = [False] * 2
+
+ for machine in issues:
+ for issue in issues[machine]:
+ if issue['type'] == 'cross_segment':
+ warnings_byte_array[ReportService.WARNINGS_DICT.CROSS_SEGMENT] = True
+ elif issue['type'] == 'tunnel':
+ warnings_byte_array[ReportService.WARNINGS_DICT.TUNNEL] = True
+
+ return warnings_byte_array
+
@staticmethod
def get_report():
+ issues = ReportService.get_issues()
+ config_users = ReportService.get_config_users()
+ config_passwords = ReportService.get_config_passwords()
+
return \
{
'overview':
{
'manual_monkeys': ReportService.get_manual_monkeys(),
- 'config_users': ReportService.get_config_users(),
- 'config_passwords': ReportService.get_config_passwords(),
+ 'config_users': config_users,
+ 'config_passwords': config_passwords,
'config_exploits': ReportService.get_config_exploits(),
'config_ips': ReportService.get_config_ips(),
'config_scan': ReportService.get_config_scan(),
'monkey_start_time': ReportService.get_first_monkey_time().strftime("%d/%m/%Y %H:%M:%S"),
'monkey_duration': ReportService.get_monkey_duration(),
- 'issues': [False, True, True, True, False, True],
- 'warnings': [True, True]
+ 'issues': ReportService.get_issues_overview(issues, config_users, config_passwords),
+ 'warnings': ReportService.get_warnings_overview(issues)
},
'glance':
{
@@ -340,7 +392,7 @@ class ReportService:
},
'recommendations':
{
- 'issues': ReportService.get_issues()
+ 'issues': issues
}
}
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index a058ce516..e5e1fd3af 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -498,46 +498,70 @@ class ReportPageComponent extends React.Component {
Immediate Threats
- During this simulated attack the Monkey uncovered {this.state.report.overview.issues.filter(function (x) {
- return x === true;
- }).length} issues:
-
Lack of Micro-segmentation, machines successfully tunneled monkey activity
+ using unused ports.
: null}
+
+
+ :
+
+ The monkey did not find any issues.
+
+ }
From 8ed439e24ed3ec7563a4acc61458d25775f94016 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 12 Dec 2017 16:39:38 +0200
Subject: [PATCH 46/62] Remove irrelevant sentence+link
---
monkey_island/cc/ui/src/components/pages/ReportPage.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index e5e1fd3af..2d3022adc 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -585,8 +585,6 @@ class ReportPageComponent extends React.Component {
In addition, while attempting to exploit additional hosts , security software installed in the
network should have picked up the attack attempts and logged them.
-
- Detailed recommendations in the next part of the report.
Date: Tue, 12 Dec 2017 17:05:57 +0200
Subject: [PATCH 47/62] Show minimal info on services. Make optimization for
machine label on report
---
monkey_island/cc/services/edge.py | 19 +++++++++++--------
monkey_island/cc/services/node.py | 18 ++++++++++--------
monkey_island/cc/services/report.py | 17 ++++++++---------
3 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/monkey_island/cc/services/edge.py b/monkey_island/cc/services/edge.py
index 308a57e55..520808be8 100644
--- a/monkey_island/cc/services/edge.py
+++ b/monkey_island/cc/services/edge.py
@@ -11,22 +11,22 @@ class EdgeService:
pass
@staticmethod
- def get_displayed_edge_by_id(edge_id):
+ def get_displayed_edge_by_id(edge_id, for_report=False):
edge = mongo.db.edge.find({"_id": ObjectId(edge_id)})[0]
- return EdgeService.edge_to_displayed_edge(edge)
+ return EdgeService.edge_to_displayed_edge(edge, for_report)
@staticmethod
- def get_displayed_edges_by_to(to):
+ def get_displayed_edges_by_to(to, for_report=False):
edges = mongo.db.edge.find({"to": ObjectId(to)})
- return [EdgeService.edge_to_displayed_edge(edge) for edge in edges]
+ return [EdgeService.edge_to_displayed_edge(edge, for_report) for edge in edges]
@staticmethod
- def edge_to_displayed_edge(edge):
+ def edge_to_displayed_edge(edge, for_report=False):
services = []
os = {}
if len(edge["scans"]) > 0:
- services = EdgeService.services_to_displayed_services(edge["scans"][-1]["data"]["services"])
+ services = EdgeService.services_to_displayed_services(edge["scans"][-1]["data"]["services"], for_report)
os = edge["scans"][-1]["data"]["os"]
displayed_edge = EdgeService.edge_to_net_edge(edge)
@@ -104,8 +104,11 @@ class EdgeService:
return edges
@staticmethod
- def services_to_displayed_services(services):
- return [x + ": " + (services[x]['name'] if services[x].has_key('name') else 'unknown') for x in services]
+ def services_to_displayed_services(services, for_report=False):
+ if for_report:
+ return [x for x in services]
+ else:
+ return [x + ": " + (services[x]['name'] if 'name' in services[x] else 'unknown') for x in services]
@staticmethod
def edge_to_net_edge(edge):
diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py
index 21c2ef194..a6ce09438 100644
--- a/monkey_island/cc/services/node.py
+++ b/monkey_island/cc/services/node.py
@@ -12,11 +12,11 @@ class NodeService:
pass
@staticmethod
- def get_displayed_node_by_id(node_id):
+ def get_displayed_node_by_id(node_id, for_report=False):
if ObjectId(node_id) == NodeService.get_monkey_island_pseudo_id():
return NodeService.get_monkey_island_node()
- edges = EdgeService.get_displayed_edges_by_to(node_id)
+ edges = EdgeService.get_displayed_edges_by_to(node_id, for_report)
accessible_from_nodes = []
exploits = []
@@ -29,14 +29,14 @@ class NodeService:
return new_node
# node is infected
- new_node = NodeService.monkey_to_net_node(monkey)
+ new_node = NodeService.monkey_to_net_node(monkey, for_report)
for key in monkey:
if key not in ['_id', 'modifytime', 'parent', 'dead', 'description']:
new_node[key] = monkey[key]
else:
# node is uninfected
- new_node = NodeService.node_to_net_node(node)
+ new_node = NodeService.node_to_net_node(node, for_report)
new_node["ip_addresses"] = node["ip_addresses"]
for edge in edges:
@@ -119,22 +119,24 @@ class NodeService:
return "%s_%s" % (node_type, node_os)
@staticmethod
- def monkey_to_net_node(monkey):
+ def monkey_to_net_node(monkey, for_report=False):
+ label = monkey['hostname'] if for_report else NodeService.get_monkey_label(monkey)
return \
{
"id": monkey["_id"],
- "label": NodeService.get_monkey_label(monkey),
+ "label": label,
"group": NodeService.get_monkey_group(monkey),
"os": NodeService.get_monkey_os(monkey),
"dead": monkey["dead"],
}
@staticmethod
- def node_to_net_node(node):
+ def node_to_net_node(node, for_report=False):
+ label = node['os']['version'] if for_report else NodeService.get_node_label(node)
return \
{
"id": node["_id"],
- "label": NodeService.get_node_label(node),
+ "label": label,
"group": NodeService.get_node_group(node),
"os": NodeService.get_node_os(node)
}
diff --git a/monkey_island/cc/services/report.py b/monkey_island/cc/services/report.py
index 4b3bf8573..ac445ac6a 100644
--- a/monkey_island/cc/services/report.py
+++ b/monkey_island/cc/services/report.py
@@ -76,17 +76,16 @@ class ReportService:
@staticmethod
def get_scanned():
nodes = \
- [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(node['_id'], True) for node in mongo.db.node.find({}, {'_id': 1})] \
+ + [NodeService.get_displayed_node_by_id(monkey['_id'], True) for monkey in mongo.db.monkey.find({}, {'_id': 1})]
nodes = [
{
- 'label':
- node['hostname'] if 'hostname' in node else NodeService.get_node_by_id(node['id'])['os']['version'],
+ 'label': node['label'],
'ip_addresses': node['ip_addresses'],
'accessible_from_nodes':
(x['hostname'] for x in
- (NodeService.get_displayed_node_by_id(edge['from'])
- for edge in EdgeService.get_displayed_edges_by_to(node['id']))),
+ (NodeService.get_displayed_node_by_id(edge['from'], True)
+ for edge in EdgeService.get_displayed_edges_by_to(node['id'], True))),
'services': node['services']
}
for node in nodes]
@@ -96,14 +95,14 @@ class ReportService:
@staticmethod
def get_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'], True) for monkey in mongo.db.monkey.find({}, {'_id': 1})
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'], True)
for node in mongo.db.node.find({'exploited': True}, {'_id': 1})]
exploited = [
{
- 'label': NodeService.get_node_hostname(NodeService.get_node_or_monkey_by_id(monkey['id'])),
+ 'label': monkey['label'],
'ip_addresses': monkey['ip_addresses'],
'exploits': list(set(
[ReportService.EXPLOIT_DISPLAY_DICT[exploit['exploiter']] for exploit in monkey['exploits'] if
From b0547c4f7a4c38abe80c1b55846f84018cbd8419 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 19 Dec 2017 17:58:07 +0200
Subject: [PATCH 48/62] Add legend to report map
---
monkey_island/cc/ui/src/components/pages/ReportPage.js | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 2d3022adc..1ef8b2f30 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -596,6 +596,16 @@ class ReportPageComponent extends React.Component {
From the attacker's point of view, the network looks like this:
+
+ Legend:
+ Exploit
+ |
+ Scan
+ |
+ Tunnel
+ |
+ Island Communication
+
Lack of Micro-segmentation, machines successfully tunneled monkey activity
+
Lack of machine hardening, machines successfully tunneled monkey traffic
using unused ports.
: null}
From 0c286a3419b91556395406869e684acd8cc759c8 Mon Sep 17 00:00:00 2001
From: Itay Mizeretz
Date: Tue, 19 Dec 2017 19:02:10 +0200
Subject: [PATCH 50/62] Remove statement if there were no infections
---
.../cc/ui/src/components/pages/ReportPage.js | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index 50e0921cf..d9f3255e2 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -582,10 +582,16 @@ class ReportPageComponent extends React.Component {
className="label label-warning">{this.state.report.glance.scanned.length} machines and
successfully breached {this.state.report.glance.exploited.length} of them.
-
- In addition, while attempting to exploit additional hosts , security software installed in the
- network should have picked up the attack attempts and logged them.
+ {
+ this.state.report.glance.exploited.length > 0 ?
+
+ In addition, while attempting to exploit additional hosts , security software installed in the
+ network should have picked up the attack attempts and logged them.
+
+ :
+ ''
+ }
Date: Tue, 19 Dec 2017 20:35:06 +0200
Subject: [PATCH 51/62] Remove unecessary paragraph
---
monkey_island/cc/ui/src/components/pages/ReportPage.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/monkey_island/cc/ui/src/components/pages/ReportPage.js b/monkey_island/cc/ui/src/components/pages/ReportPage.js
index d9f3255e2..f85698f31 100644
--- a/monkey_island/cc/ui/src/components/pages/ReportPage.js
+++ b/monkey_island/cc/ui/src/components/pages/ReportPage.js
@@ -486,9 +486,6 @@ class ReportPageComponent extends React.Component {
Monkeys were configured to avoid scanning of the local network.
}
-
- A full report of the Monkeys activities follows.
-
- In addition, while attempting to exploit additional hosts , security software installed in the
+ In addition, while attempting to exploit additional hosts, security software installed in the
network should have picked up the attack attempts and logged them.
:
@@ -603,13 +604,13 @@ class ReportPageComponent extends React.Component {
Legend:
- Exploit
+ Exploit |
- Scan
+ Scan |
- Tunnel
+ Tunnel |
- Island Communication
+ Island Communication
@@ -628,7 +629,7 @@ class ReportPageComponent extends React.Component {
For questions, suggestions or any other feedback
contact: labs@guardicore.com