Island: Add "/legacy" config format option to monkey config endpoint

The schema of the configuration that is given to the agent when it
requests configuration from the island is heavily influenced by the GUI
and how configuration options should be displayed to the user. It is not
formatted in a way that is easy for the agent to utilize. This commit
adds a `/api/monkey/<string:guid>/<string:config_format>` endpoint that
allows legacy code to continue to function, while the agent's new
AutomatedMaster component (issue #1597) can receive configuration in a
way that makes sense for the agent.
This commit is contained in:
Mike Salvatore 2021-12-02 20:17:21 -05:00
parent 21a9c4fa14
commit 7cda2b8e58
3 changed files with 20 additions and 3 deletions

View File

@ -122,7 +122,13 @@ def init_api_resources(api):
api.add_resource(Root, "/api")
api.add_resource(Registration, "/api/registration")
api.add_resource(Authenticate, "/api/auth")
api.add_resource(Monkey, "/api/monkey", "/api/monkey/", "/api/monkey/<string:guid>")
api.add_resource(
Monkey,
"/api/monkey",
"/api/monkey/",
"/api/monkey/<string:guid>",
"/api/monkey/<string:guid>/<string:config_format>",
)
api.add_resource(Bootloader, "/api/bootloader/<string:os>")
api.add_resource(LocalRun, "/api/local-monkey", "/api/local-monkey/")
api.add_resource(ClientRun, "/api/client-monkey", "/api/client-monkey/")

View File

@ -19,14 +19,20 @@ from monkey_island.cc.services.node import NodeService
class Monkey(flask_restful.Resource):
# Used by monkey. can't secure.
def get(self, guid=None, **kw):
def get(self, guid=None, config_format=None, **kw):
NodeService.update_dead_monkeys() # refresh monkeys status
if not guid:
guid = request.args.get("guid")
if guid:
monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid})
monkey_json["config"] = ConfigService.decrypt_flat_config(monkey_json["config"])
# TODO: When the "legacy" format is no longer needed, update this logic and remove the
# "/api/monkey/<string:guid>/<string:config_format>" route.
if config_format == "legacy":
ConfigService.decrypt_flat_config(monkey_json["config"])
else:
ConfigService.format_config_for_agent(monkey_json["config"])
return monkey_json
return {}

View File

@ -2,6 +2,7 @@ import collections
import copy
import functools
import logging
from typing import Dict
from jsonschema import Draft4Validator, validators
@ -425,3 +426,7 @@ class ConfigService:
),
"exploit_ssh_keys": ConfigService.get_config_value(SSH_KEYS_PATH, should_decrypt=False),
}
@staticmethod
def format_config_for_agent(config: Dict):
ConfigService.decrypt_flat_config(config)