diff --git a/monkey_island/cc/app.py b/monkey_island/cc/app.py index 4d98749a3..bb112020a 100644 --- a/monkey_island/cc/app.py +++ b/monkey_island/cc/app.py @@ -8,7 +8,7 @@ from cc.database import mongo from cc.resources.monkey import Monkey from cc.resources.local_run import LocalRun from cc.resources.telemetry import Telemetry -from cc.resources.new_config import NewConfig +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 @@ -17,12 +17,13 @@ from cc.resources.root import Root __author__ = 'Barak' -def send_admin(path): - return send_from_directory('admin/ui', path) +def serve_static_file(path): + print 'requested', path + return send_from_directory('ui/dist', path) -def send_to_default(): - return redirect('/admin/index.html') +def serve_home(): + return serve_static_file('index.html') def normalize_obj(obj): @@ -44,30 +45,22 @@ def normalize_obj(obj): return obj -def output_json(obj, code, headers=None): - obj = normalize_obj(obj) - resp = make_response(bson.json_util.dumps(obj), code) - resp.headers.extend(headers or {}) - return resp - - def init_app(mongo_url): app = Flask(__name__) api = flask_restful.Api(app) - api.representations = {'application/json': output_json} app.config['MONGO_URI'] = mongo_url mongo.init_app(app) - app.add_url_rule('/', 'send_to_default', send_to_default) - app.add_url_rule('/admin/', 'send_admin', send_admin) + app.add_url_rule('/', 'serve_home', serve_home) + app.add_url_rule('/', 'serve_static_file', serve_static_file) api.add_resource(Root, '/api') api.add_resource(Monkey, '/api/monkey', '/api/monkey/', '/api/monkey/') api.add_resource(LocalRun, '/api/island', '/api/island/') api.add_resource(Telemetry, '/api/telemetry', '/api/telemetry/', '/api/telemetry/') - api.add_resource(NewConfig, '/api/config/new', '/api/config/new/') + api.add_resource(MonkeyConfiguration, '/api/configuration', '/api/configuration/') api.add_resource(MonkeyDownload, '/api/monkey/download', '/api/monkey/download/', '/api/monkey/download/') api.add_resource(NetMap, '/api/netmap', '/api/netmap/') diff --git a/monkey_island/cc/main.py b/monkey_island/cc/main.py index 754f5076f..ad3156431 100644 --- a/monkey_island/cc/main.py +++ b/monkey_island/cc/main.py @@ -8,7 +8,7 @@ if BASE_PATH not in sys.path: sys.path.insert(0, BASE_PATH) from cc.app import init_app -from cc.utils import init_collections +from cc.utils import init_collections, local_ip_addresses ISLAND_PORT = 5000 DEFAULT_MONGO_URL = "mongodb://localhost:27017/monkeyisland" @@ -29,5 +29,6 @@ if __name__ == '__main__': 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')) diff --git a/monkey_island/cc/resources/monkey_configuration.py b/monkey_island/cc/resources/monkey_configuration.py new file mode 100644 index 000000000..2135bc640 --- /dev/null +++ b/monkey_island/cc/resources/monkey_configuration.py @@ -0,0 +1,40 @@ +import json + +from flask import request, jsonify +import flask_restful + +from cc.database import mongo + +__author__ = 'Barak' + + +SCHEMA = { + 'type': 'object', + 'title': 'Monkey', + 'properties': { + 'alive': { + 'title': 'Alive', + 'type': 'boolean' + } + }, + 'options': { + 'collapsed': True + } +} + + +class MonkeyConfiguration(flask_restful.Resource): + def get(self): + return jsonify(schema=SCHEMA, configuration=self._get_configuration()) + + def post(self): + config_json = json.loads(request.data) + mongo.db.config.update({'name': 'newconfig'}, {"$set": config_json}, upsert=True) + return jsonify(schema=SCHEMA, configuration=self._get_configuration()) + + @classmethod + def _get_configuration(cls): + config = mongo.db.config.find_one({'name': 'newconfig'}) or {} + for field in ('name', '_id'): + config.pop(field, None) + return config diff --git a/monkey_island/cc/resources/new_config.py b/monkey_island/cc/resources/new_config.py deleted file mode 100644 index 4d15d1611..000000000 --- a/monkey_island/cc/resources/new_config.py +++ /dev/null @@ -1,20 +0,0 @@ -import json - -from flask import request -import flask_restful - -from cc.database import mongo - -__author__ = 'Barak' - - -class NewConfig(flask_restful.Resource): - def get(self): - config = mongo.db.config.find_one({'name': 'newconfig'}) or {} - if 'name' in config: - del config['name'] - return config - - def post(self): - config_json = json.loads(request.data) - return mongo.db.config.update({'name': 'newconfig'}, {"$set": config_json}, upsert=True) diff --git a/monkey_island/cc/resources/root.py b/monkey_island/cc/resources/root.py index 2d7af1eb6..98b0b9b30 100644 --- a/monkey_island/cc/resources/root.py +++ b/monkey_island/cc/resources/root.py @@ -1,11 +1,11 @@ from datetime import datetime -from flask import request +from flask import request, make_response, jsonify import flask_restful from cc.database import mongo -from cc.utils import init_collections +from cc.utils import init_collections, local_ip_addresses __author__ = 'Barak' @@ -14,11 +14,10 @@ class Root(flask_restful.Resource): def get(self, action=None): if not action: action = request.args.get('action') + if not action: - return { - 'status': 'OK', - 'mongo': str(mongo.db), - } + return jsonify(ip=local_ip_addresses()[0], mongo=str(mongo.db)) + elif action == "reset": mongo.db.config.drop() mongo.db.monkey.drop() @@ -28,15 +27,10 @@ class Root(flask_restful.Resource): mongo.db.node.drop() mongo.db.edge.drop() init_collections() - return { - 'status': 'OK', - } + return jsonify(status='OK') elif action == "killall": mongo.db.monkey.update({}, {'$set': {'config.alive': False, 'modifytime': datetime.now()}}, upsert=False, multi=True) - return { - 'status': 'OK', - } + return 200 else: - return {'status': 'BAD', - 'reason': 'unknown action'} + return make_response(400, {'error': 'unknown action'}) diff --git a/monkey_island/cc/utils.py b/monkey_island/cc/utils.py index 30530470d..0274a1051 100644 --- a/monkey_island/cc/utils.py +++ b/monkey_island/cc/utils.py @@ -4,6 +4,8 @@ import sys import array import struct +from netifaces import interfaces, ifaddresses, AF_INET + from cc.database import mongo __author__ = 'Barak' @@ -75,3 +77,11 @@ else: finally: return result # End of local ips function + + +def local_ip_addresses(): + ip_list = [] + for interface in interfaces(): + 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