From dbe7a6a378b87e25e61b17a01ae76aaff5026a4c Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Wed, 14 Feb 2018 15:50:53 +0200 Subject: [PATCH 1/8] Add log sending logic to monkey Add log processing logic to monkey island backend --- chaos_monkey/control.py | 16 +++++++++ chaos_monkey/main.py | 9 +++--- chaos_monkey/monkey.py | 13 ++++++++ chaos_monkey/utils.py | 14 ++++++++ monkey_island/cc/app.py | 13 +++++--- monkey_island/cc/resources/log.py | 29 +++++++++++++++++ monkey_island/cc/resources/root.py | 3 +- monkey_island/cc/services/log.py | 52 ++++++++++++++++++++++++++++++ monkey_island/cc/services/node.py | 6 +++- 9 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 chaos_monkey/utils.py create mode 100644 monkey_island/cc/resources/log.py create mode 100644 monkey_island/cc/services/log.py diff --git a/chaos_monkey/control.py b/chaos_monkey/control.py index b4f2769cd..fef37de1f 100644 --- a/chaos_monkey/control.py +++ b/chaos_monkey/control.py @@ -1,3 +1,4 @@ +import base64 import json import logging import platform @@ -111,6 +112,21 @@ class ControlClient(object): LOG.warn("Error connecting to control server %s: %s", WormConfiguration.current_server, exc) + @staticmethod + def send_log(log): + if not WormConfiguration.current_server: + return + try: + telemetry = {'monkey_guid': GUID, 'log': base64.b64encode(log)} + reply = requests.post("https://%s/api/log" % (WormConfiguration.current_server,), + data=json.dumps(telemetry), + headers={'content-type': 'application/json'}, + verify=False, + proxies=ControlClient.proxies) + except Exception as exc: + LOG.warn("Error connecting to control server %s: %s", + WormConfiguration.current_server, exc) + @staticmethod def load_control_config(): if not WormConfiguration.current_server: diff --git a/chaos_monkey/main.py b/chaos_monkey/main.py index c53232b2c..ef57492cc 100644 --- a/chaos_monkey/main.py +++ b/chaos_monkey/main.py @@ -12,6 +12,7 @@ from config import WormConfiguration, EXTERNAL_CONFIG_FILE from dropper import MonkeyDrops from model import MONKEY_ARG, DROPPER_ARG from monkey import ChaosMonkey +import utils if __name__ == "__main__": sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) @@ -78,12 +79,10 @@ def main(): try: if MONKEY_ARG == monkey_mode: - log_path = os.path.expandvars( - WormConfiguration.monkey_log_path_windows) if sys.platform == "win32" else WormConfiguration.monkey_log_path_linux + log_path = utils.get_monkey_log_path() monkey_cls = ChaosMonkey elif DROPPER_ARG == monkey_mode: - log_path = os.path.expandvars( - WormConfiguration.dropper_log_path_windows) if sys.platform == "win32" else WormConfiguration.dropper_log_path_linux + log_path = utils.get_dropper_log_path() monkey_cls = MonkeyDrops else: return True @@ -91,6 +90,8 @@ def main(): return True if WormConfiguration.use_file_logging: + if os.path.exists(log_path): + os.remove(log_path) LOG_CONFIG['handlers']['file']['filename'] = log_path LOG_CONFIG['root']['handlers'].append('file') else: diff --git a/chaos_monkey/monkey.py b/chaos_monkey/monkey.py index 79012dc39..79e8bf3ec 100644 --- a/chaos_monkey/monkey.py +++ b/chaos_monkey/monkey.py @@ -6,6 +6,7 @@ import sys import time import tunnel +import utils from config import WormConfiguration from control import ControlClient from model import DELAY_DELETE_CMD @@ -226,6 +227,8 @@ class ChaosMonkey(object): firewall.close() + self.send_log() + self._singleton.unlock() if WormConfiguration.self_delete_in_cleanup and -1 == sys.executable.find('python'): @@ -244,3 +247,13 @@ class ChaosMonkey(object): LOG.error("Exception in self delete: %s", exc) LOG.info("Monkey is shutting down") + + def send_log(self): + monkey_log_path = utils.get_monkey_log_path() + if os.path.exists(monkey_log_path): + with open(monkey_log_path, 'r') as f: + log = f.read() + else: + log = '' + + ControlClient.send_log(log) diff --git a/chaos_monkey/utils.py b/chaos_monkey/utils.py new file mode 100644 index 000000000..d95407341 --- /dev/null +++ b/chaos_monkey/utils.py @@ -0,0 +1,14 @@ +import os +import sys + +from config import WormConfiguration + + +def get_monkey_log_path(): + return os.path.expandvars(WormConfiguration.monkey_log_path_windows) if sys.platform == "win32" \ + else WormConfiguration.monkey_log_path_linux + + +def get_dropper_log_path(): + return os.path.expandvars(WormConfiguration.dropper_log_path_windows) if sys.platform == "win32" \ + else WormConfiguration.dropper_log_path_linux diff --git a/monkey_island/cc/app.py b/monkey_island/cc/app.py index 9c85f6230..2d8041eb0 100644 --- a/monkey_island/cc/app.py +++ b/monkey_island/cc/app.py @@ -1,22 +1,24 @@ from datetime import datetime + import bson -from bson.json_util import dumps -from flask import Flask, send_from_directory, redirect, make_response import flask_restful +from bson.json_util import dumps +from flask import Flask, send_from_directory, make_response from werkzeug.exceptions import NotFound from cc.database import mongo from cc.resources.client_run import ClientRun -from cc.resources.monkey import Monkey +from cc.resources.edge import Edge from cc.resources.local_run import LocalRun -from cc.resources.telemetry import Telemetry +from cc.resources.log import Log +from cc.resources.monkey import Monkey from cc.resources.monkey_configuration import MonkeyConfiguration 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.resources.telemetry import Telemetry from cc.resources.telemetry_feed import TelemetryFeed from cc.services.config import ConfigService @@ -91,5 +93,6 @@ def init_app(mongo_url): api.add_resource(Node, '/api/netmap/node', '/api/netmap/node/') api.add_resource(Report, '/api/report', '/api/report/') api.add_resource(TelemetryFeed, '/api/telemetry-feed', '/api/telemetry-feed/') + api.add_resource(Log, '/api/log', '/api/log/') return app diff --git a/monkey_island/cc/resources/log.py b/monkey_island/cc/resources/log.py new file mode 100644 index 000000000..5a308b5dd --- /dev/null +++ b/monkey_island/cc/resources/log.py @@ -0,0 +1,29 @@ +import json + +import flask_restful +from bson import ObjectId +from flask import request + +from cc.database import mongo +from cc.services.log import LogService +from cc.services.node import NodeService + +__author__ = "itay.mizeretz" + + +class Log(flask_restful.Resource): + def get(self): + monkey_id = request.args.get('id') + exists_monkey_id = request.args.get('exists') + if monkey_id: + return LogService.get_log_by_monkey_id(ObjectId(monkey_id)) + else: + return LogService.log_exists(ObjectId(exists_monkey_id)) + + def post(self): + telemetry_json = json.loads(request.data) + + monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'] + log_id = LogService.add_log(monkey_id, telemetry_json['log']) + + return mongo.db.log.find_one_or_404({"_id": log_id}) diff --git a/monkey_island/cc/resources/root.py b/monkey_island/cc/resources/root.py index 25d7dfed7..f725163aa 100644 --- a/monkey_island/cc/resources/root.py +++ b/monkey_island/cc/resources/root.py @@ -33,7 +33,8 @@ class Root(flask_restful.Resource): @staticmethod def reset_db(): - [mongo.db[x].drop() for x in ['config', 'monkey', 'telemetry', 'node', 'edge', 'report']] + [mongo.db[x].drop() for x in + ['config', 'monkey', 'telemetry', 'node', 'edge', 'report', 'log', 'fs.chunks', 'fs.files']] ConfigService.init_config() return jsonify(status='OK') diff --git a/monkey_island/cc/services/log.py b/monkey_island/cc/services/log.py new file mode 100644 index 000000000..2783a1dfa --- /dev/null +++ b/monkey_island/cc/services/log.py @@ -0,0 +1,52 @@ +from datetime import datetime + +import gridfs + +import cc.services.node +from cc.database import mongo + +__author__ = "itay.mizeretz" + + +class LogService: + def __init__(self): + pass + + @staticmethod + def get_log_by_monkey_id(monkey_id): + log = mongo.db.log.find_one({'monkey_id': monkey_id}) + if log: + fs = gridfs.GridFS(mongo.db) + log_file = fs.get(log['file_id']) + monkey_label = cc.services.node.NodeService.get_monkey_label( + cc.services.node.NodeService.get_monkey_by_id(log['monkey_id'])) + return \ + { + 'monkey_label': monkey_label, + 'log': log_file.read(), + 'timestamp': log['timestamp'] + } + + @staticmethod + def remove_logs_by_monkey_id(monkey_id): + fs = gridfs.GridFS(mongo.db) + for log in mongo.db.log.find({'monkey_id': monkey_id}): + fs.delete(log['file_id']) + mongo.db.log.delete_many({'monkey_id': monkey_id}) + + @staticmethod + def add_log(monkey_id, log_data, timestamp=datetime.now()): + LogService.remove_logs_by_monkey_id(monkey_id) + fs = gridfs.GridFS(mongo.db) + file_id = fs.put(log_data) + return mongo.db.log.insert( + { + 'monkey_id': monkey_id, + 'file_id': file_id, + 'timestamp': timestamp + } + ) + + @staticmethod + def log_exists(monkey_id): + return mongo.db.log.find_one({'monkey_id': monkey_id}) is not None diff --git a/monkey_island/cc/services/node.py b/monkey_island/cc/services/node.py index 47cfba8d9..47cd9cd21 100644 --- a/monkey_island/cc/services/node.py +++ b/monkey_island/cc/services/node.py @@ -1,9 +1,12 @@ from datetime import datetime, timedelta + from bson import ObjectId +import cc.services.log from cc.database import mongo from cc.services.edge import EdgeService from cc.utils import local_ip_addresses + __author__ = "itay.mizeretz" @@ -54,6 +57,7 @@ class NodeService: else: new_node["services"] = [] + new_node['has_log'] = cc.services.log.LogService.log_exists(ObjectId(node_id)) return new_node @staticmethod @@ -241,7 +245,7 @@ class NodeService: @staticmethod def get_monkey_island_pseudo_net_node(): - return\ + return \ { "id": NodeService.get_monkey_island_pseudo_id(), "label": "MonkeyIsland", From 86a0e47d15afde8be46ccdadb5eaebe751b7556d Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Wed, 14 Feb 2018 15:51:22 +0200 Subject: [PATCH 2/8] Add log downloading from map --- monkey_island/cc/ui/package.json | 1 + .../map/preview-pane/PreviewPane.js | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/monkey_island/cc/ui/package.json b/monkey_island/cc/ui/package.json index 5ee2e5389..27b536365 100644 --- a/monkey_island/cc/ui/package.json +++ b/monkey_island/cc/ui/package.json @@ -63,6 +63,7 @@ "dependencies": { "bootstrap": "^3.3.7", "core-js": "^2.5.1", + "downloadjs": "^1.4.7", "fetch": "^1.1.0", "js-file-download": "^0.4.1", "normalize.css": "^4.0.0", diff --git a/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js b/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js index 842440149..56c6d0e75 100644 --- a/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js +++ b/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js @@ -2,6 +2,7 @@ import React from 'react'; import {Icon} from 'react-fa'; import Toggle from 'react-toggle'; import {OverlayTrigger, Tooltip} from 'react-bootstrap'; +import download from 'downloadjs' class PreviewPaneComponent extends React.Component { @@ -88,6 +89,34 @@ class PreviewPaneComponent extends React.Component { ); } + downloadLog(asset) { + + fetch('/api/log?id=' + asset.id) + .then(res => res.json()) + .then(res => { + let timestamp = res['timestamp']; + timestamp = timestamp.substr(0, timestamp.indexOf('.')); + let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log'; + download(atob(res['log']), filename, 'text/plain'); + }); + + } + + downloadLogRow(asset) { + return ( + + + Download Log + + + this.downloadLog(asset)}>Download + + + ); + } + exploitsTimeline(asset) { if (asset.exploits.length === 0) { return (
); @@ -140,6 +169,7 @@ class PreviewPaneComponent extends React.Component { {this.servicesRow(asset)} {this.accessibleRow(asset)} {this.forceKillRow(asset)} + {this.downloadLogRow(asset)} {this.exploitsTimeline(asset)} From 70766e7358556bec80524b25c010cbc62734e5ff Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Wed, 14 Feb 2018 16:58:58 +0200 Subject: [PATCH 3/8] Save some space --- monkey_island/cc/resources/log.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey_island/cc/resources/log.py b/monkey_island/cc/resources/log.py index 5a308b5dd..e49c7024d 100644 --- a/monkey_island/cc/resources/log.py +++ b/monkey_island/cc/resources/log.py @@ -24,6 +24,8 @@ class Log(flask_restful.Resource): telemetry_json = json.loads(request.data) monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'] - log_id = LogService.add_log(monkey_id, telemetry_json['log']) + # This is base64 so no data will be lost. this'll take 2 time less space. + log_data = str(telemetry_json['log']) + log_id = LogService.add_log(monkey_id, log_data) return mongo.db.log.find_one_or_404({"_id": log_id}) From aa02d8945dc32121e12f7fb530ca79d5e74ca107 Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Mon, 19 Feb 2018 17:22:48 +0200 Subject: [PATCH 4/8] Replace base64 with string escaping --- chaos_monkey/control.py | 3 +- .../map/preview-pane/PreviewPane.js | 60 +++++++++++-------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/chaos_monkey/control.py b/chaos_monkey/control.py index fef37de1f..dd1814133 100644 --- a/chaos_monkey/control.py +++ b/chaos_monkey/control.py @@ -1,4 +1,3 @@ -import base64 import json import logging import platform @@ -117,7 +116,7 @@ class ControlClient(object): if not WormConfiguration.current_server: return try: - telemetry = {'monkey_guid': GUID, 'log': base64.b64encode(log)} + telemetry = {'monkey_guid': GUID, 'log': json.dumps(log)} reply = requests.post("https://%s/api/log" % (WormConfiguration.current_server,), data=json.dumps(telemetry), headers={'content-type': 'application/json'}, diff --git a/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js b/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js index 56c6d0e75..b7f055103 100644 --- a/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js +++ b/monkey_island/cc/ui/src/components/map/preview-pane/PreviewPane.js @@ -82,22 +82,34 @@ class PreviewPaneComponent extends React.Component { this.forceKill(e, asset)} /> + onChange={(e) => this.forceKill(e, asset)}/> ); } - downloadLog(asset) { + unescapeLog(st) { + return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string. + .replace(/\\n/g, "\n") + .replace(/\\r/g, "\r") + .replace(/\\t/g, "\t") + .replace(/\\b/g, "\b") + .replace(/\\f/g, "\f") + .replace(/\\"/g, '\"') + .replace(/\\'/g, "\'") + .replace(/\\&/g, "\&"); + } + downloadLog(asset) { fetch('/api/log?id=' + asset.id) .then(res => res.json()) .then(res => { let timestamp = res['timestamp']; timestamp = timestamp.substr(0, timestamp.indexOf('.')); let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log'; - download(atob(res['log']), filename, 'text/plain'); + let logContent = this.unescapeLog(res['log']); + download(logContent, filename, 'text/plain'); }); } @@ -119,7 +131,7 @@ class PreviewPaneComponent extends React.Component { exploitsTimeline(asset) { if (asset.exploits.length === 0) { - return (
); + return (
); } return ( @@ -129,9 +141,9 @@ class PreviewPaneComponent extends React.Component { {this.generateToolTip('Timeline of exploit attempts. Red is successful. Gray is unsuccessful')}
    - { asset.exploits.map(exploit => + {asset.exploits.map(exploit =>
  • -
    +
    {new Date(exploit.timestamp).toLocaleString()}
    {exploit.origin}
    {exploit.exploiter}
    @@ -147,10 +159,10 @@ class PreviewPaneComponent extends React.Component {
    - {this.osRow(asset)} - {this.ipsRow(asset)} - {this.servicesRow(asset)} - {this.accessibleRow(asset)} + {this.osRow(asset)} + {this.ipsRow(asset)} + {this.servicesRow(asset)} + {this.accessibleRow(asset)}
    {this.exploitsTimeline(asset)} @@ -163,13 +175,13 @@ class PreviewPaneComponent extends React.Component {
    - {this.osRow(asset)} - {this.statusRow(asset)} - {this.ipsRow(asset)} - {this.servicesRow(asset)} - {this.accessibleRow(asset)} - {this.forceKillRow(asset)} - {this.downloadLogRow(asset)} + {this.osRow(asset)} + {this.statusRow(asset)} + {this.ipsRow(asset)} + {this.servicesRow(asset)} + {this.accessibleRow(asset)} + {this.forceKillRow(asset)} + {this.downloadLogRow(asset)}
    {this.exploitsTimeline(asset)} @@ -202,9 +214,9 @@ class PreviewPaneComponent extends React.Component {

    Timeline

      - { edge.exploits.map(exploit => + {edge.exploits.map(exploit =>
    • -
      +
      {new Date(exploit.timestamp).toLocaleString()}
      {exploit.origin}
      {exploit.exploiter}
      @@ -235,8 +247,8 @@ class PreviewPaneComponent extends React.Component { this.infectedAssetInfo(this.props.item) : this.assetInfo(this.props.item); break; case 'island_edge': - info = this.islandEdgeInfo(); - break; + info = this.islandEdgeInfo(); + break; } let label = ''; @@ -250,12 +262,12 @@ class PreviewPaneComponent extends React.Component { return (
      - { !info ? + {!info ? - + Select an item on the map for a detailed look - : + :

      {label} From ee1a321416bc7e35a115ba3ed6f32f20ddde8f0f Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Mon, 19 Feb 2018 18:32:05 +0200 Subject: [PATCH 5/8] Send log to island is configurable --- chaos_monkey/config.py | 1 + chaos_monkey/example.conf | 1 + chaos_monkey/monkey.py | 3 ++- monkey_island/cc/services/config.py | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py index e62820816..9ec784594 100644 --- a/chaos_monkey/config.py +++ b/chaos_monkey/config.py @@ -106,6 +106,7 @@ class Configuration(object): dropper_log_path_linux = '/tmp/user-1562' monkey_log_path_windows = '%temp%\\~df1563.tmp' monkey_log_path_linux = '/tmp/user-1563' + send_log_to_server = True ########################### # dropper config diff --git a/chaos_monkey/example.conf b/chaos_monkey/example.conf index 6f70f888a..13fa33492 100644 --- a/chaos_monkey/example.conf +++ b/chaos_monkey/example.conf @@ -48,6 +48,7 @@ "max_iterations": 3, "monkey_log_path_windows": "%temp%\\~df1563.tmp", "monkey_log_path_linux": "/tmp/user-1563", + "send_log_to_server": true, "ms08_067_exploit_attempts": 5, "ms08_067_remote_user_add": "Monkey_IUSER_SUPPORT", "ms08_067_remote_user_pass": "Password1!", diff --git a/chaos_monkey/monkey.py b/chaos_monkey/monkey.py index 79e8bf3ec..530e0785e 100644 --- a/chaos_monkey/monkey.py +++ b/chaos_monkey/monkey.py @@ -227,7 +227,8 @@ class ChaosMonkey(object): firewall.close() - self.send_log() + if WormConfiguration.send_log_to_server: + self.send_log() self._singleton.unlock() diff --git a/monkey_island/cc/services/config.py b/monkey_island/cc/services/config.py index ea755312f..e9822ea75 100644 --- a/monkey_island/cc/services/config.py +++ b/monkey_island/cc/services/config.py @@ -483,6 +483,12 @@ SCHEMA = { "type": "string", "default": "%temp%\\~df1563.tmp", "description": "The fullpath of the monkey log file on Windows" + }, + "send_log_to_server": { + "title": "Send log to server", + "type": "boolean", + "default": True, + "description": "Determines whether the monkey sends its log to the Monkey Island server" } } }, From e11a75eb48f20f4e88a903a4c70cdc2282e24b3f Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Mon, 19 Feb 2018 18:32:43 +0200 Subject: [PATCH 6/8] Exceptions are logged and sent to island --- chaos_monkey/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chaos_monkey/main.py b/chaos_monkey/main.py index ef57492cc..6bebc8cef 100644 --- a/chaos_monkey/main.py +++ b/chaos_monkey/main.py @@ -121,6 +121,8 @@ def main(): json.dump(json_dict, config_fo, skipkeys=True, sort_keys=True, indent=4, separators=(',', ': ')) return True + except Exception: + LOG.exception("Exception thrown from monkey's start function") finally: monkey.cleanup() From d8946feb69b5d26f1298df0d6b5bd6f89fe00703 Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Tue, 27 Feb 2018 19:13:28 +0200 Subject: [PATCH 7/8] Fix CR --- monkey_island/cc/app.py | 3 ++- monkey_island/cc/database.py | 15 +++++++++++++-- monkey_island/cc/resources/log.py | 2 +- monkey_island/cc/resources/root.py | 3 +-- monkey_island/cc/services/log.py | 18 +++++++----------- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/monkey_island/cc/app.py b/monkey_island/cc/app.py index 2d8041eb0..1d632f6fa 100644 --- a/monkey_island/cc/app.py +++ b/monkey_island/cc/app.py @@ -6,7 +6,7 @@ from bson.json_util import dumps from flask import Flask, send_from_directory, make_response from werkzeug.exceptions import NotFound -from cc.database import mongo +from cc.database import mongo, database from cc.resources.client_run import ClientRun from cc.resources.edge import Edge from cc.resources.local_run import LocalRun @@ -75,6 +75,7 @@ def init_app(mongo_url): mongo.init_app(app) with app.app_context(): + database.init() ConfigService.init_config() app.add_url_rule('/', 'serve_home', serve_home) diff --git a/monkey_island/cc/database.py b/monkey_island/cc/database.py index fadff853d..8fb3b120b 100644 --- a/monkey_island/cc/database.py +++ b/monkey_island/cc/database.py @@ -1,5 +1,5 @@ -from flask_pymongo import PyMongo -from flask_pymongo import MongoClient +import gridfs +from flask_pymongo import MongoClient, PyMongo from pymongo.errors import ServerSelectionTimeoutError __author__ = 'Barak' @@ -7,6 +7,17 @@ __author__ = 'Barak' mongo = PyMongo() +class Database: + def __init__(self): + self.gridfs = None + + def init(self): + self.gridfs = gridfs.GridFS(mongo.db) + + +database = Database() + + def is_db_server_up(mongo_url): client = MongoClient(mongo_url, serverSelectionTimeoutMS=100) try: diff --git a/monkey_island/cc/resources/log.py b/monkey_island/cc/resources/log.py index e49c7024d..76e802f0a 100644 --- a/monkey_island/cc/resources/log.py +++ b/monkey_island/cc/resources/log.py @@ -24,7 +24,7 @@ class Log(flask_restful.Resource): telemetry_json = json.loads(request.data) monkey_id = NodeService.get_monkey_by_guid(telemetry_json['monkey_guid'])['_id'] - # This is base64 so no data will be lost. this'll take 2 time less space. + # This shouldn't contain any unicode characters. this'll take 2 time less space. log_data = str(telemetry_json['log']) log_id = LogService.add_log(monkey_id, log_data) diff --git a/monkey_island/cc/resources/root.py b/monkey_island/cc/resources/root.py index f725163aa..3acb870cf 100644 --- a/monkey_island/cc/resources/root.py +++ b/monkey_island/cc/resources/root.py @@ -33,8 +33,7 @@ class Root(flask_restful.Resource): @staticmethod def reset_db(): - [mongo.db[x].drop() for x in - ['config', 'monkey', 'telemetry', 'node', 'edge', 'report', 'log', 'fs.chunks', 'fs.files']] + [mongo.db[x].drop() for x in mongo.db.collection_names()] ConfigService.init_config() return jsonify(status='OK') diff --git a/monkey_island/cc/services/log.py b/monkey_island/cc/services/log.py index 2783a1dfa..81603e62e 100644 --- a/monkey_island/cc/services/log.py +++ b/monkey_island/cc/services/log.py @@ -1,9 +1,7 @@ from datetime import datetime -import gridfs - import cc.services.node -from cc.database import mongo +from cc.database import mongo, database __author__ = "itay.mizeretz" @@ -16,8 +14,7 @@ class LogService: def get_log_by_monkey_id(monkey_id): log = mongo.db.log.find_one({'monkey_id': monkey_id}) if log: - fs = gridfs.GridFS(mongo.db) - log_file = fs.get(log['file_id']) + log_file = database.gridfs.get(log['file_id']) monkey_label = cc.services.node.NodeService.get_monkey_label( cc.services.node.NodeService.get_monkey_by_id(log['monkey_id'])) return \ @@ -29,16 +26,15 @@ class LogService: @staticmethod def remove_logs_by_monkey_id(monkey_id): - fs = gridfs.GridFS(mongo.db) - for log in mongo.db.log.find({'monkey_id': monkey_id}): - fs.delete(log['file_id']) - mongo.db.log.delete_many({'monkey_id': monkey_id}) + log = mongo.db.log.find_one({'monkey_id': monkey_id}) + if log is not None: + database.gridfs.delete(log['file_id']) + mongo.db.log.delete_one({'monkey_id': monkey_id}) @staticmethod def add_log(monkey_id, log_data, timestamp=datetime.now()): LogService.remove_logs_by_monkey_id(monkey_id) - fs = gridfs.GridFS(mongo.db) - file_id = fs.put(log_data) + file_id = database.gridfs.put(log_data) return mongo.db.log.insert( { 'monkey_id': monkey_id, From 7f7a20847dcc5e41a2f066daa8ce59ad6bdfb03d Mon Sep 17 00:00:00 2001 From: Itay Mizeretz Date: Tue, 27 Feb 2018 19:34:00 +0200 Subject: [PATCH 8/8] Remove utils from chaos_monkey --- chaos_monkey/utils.py | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 chaos_monkey/utils.py diff --git a/chaos_monkey/utils.py b/chaos_monkey/utils.py deleted file mode 100644 index d95407341..000000000 --- a/chaos_monkey/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -import sys - -from config import WormConfiguration - - -def get_monkey_log_path(): - return os.path.expandvars(WormConfiguration.monkey_log_path_windows) if sys.platform == "win32" \ - else WormConfiguration.monkey_log_path_linux - - -def get_dropper_log_path(): - return os.path.expandvars(WormConfiguration.dropper_log_path_windows) if sys.platform == "win32" \ - else WormConfiguration.dropper_log_path_linux