forked from p15670423/monkey
Island: Refactor monkey download to take OS and return agent file
This commit is contained in:
parent
c075fed2da
commit
0df165e140
|
@ -134,8 +134,7 @@ def init_api_resources(api):
|
||||||
api.add_resource(ConfigurationImport, "/api/configuration/import")
|
api.add_resource(ConfigurationImport, "/api/configuration/import")
|
||||||
api.add_resource(
|
api.add_resource(
|
||||||
MonkeyDownload,
|
MonkeyDownload,
|
||||||
"/api/monkey/download",
|
"/api/monkey/download/<string:host_os>",
|
||||||
"/api/monkey/download/<string:path>",
|
|
||||||
)
|
)
|
||||||
api.add_resource(NetMap, "/api/netmap")
|
api.add_resource(NetMap, "/api/netmap")
|
||||||
api.add_resource(Edge, "/api/netmap/edge")
|
api.add_resource(Edge, "/api/netmap/edge")
|
||||||
|
|
|
@ -1,63 +1,34 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
from pathlib import Path
|
||||||
|
|
||||||
import flask_restful
|
import flask_restful
|
||||||
from flask import request, send_from_directory
|
from flask import make_response, send_from_directory
|
||||||
|
|
||||||
from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
MONKEY_DOWNLOADS = [
|
AGENTS = {
|
||||||
{
|
"linux": "monkey-linux-64",
|
||||||
"type": "linux",
|
"windows": "monkey-windows-64.exe",
|
||||||
"filename": "monkey-linux-64",
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "windows",
|
|
||||||
"filename": "monkey-windows-64.exe",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def get_monkey_executable(host_os):
|
class UnsupportedOSError(Exception):
|
||||||
for download in MONKEY_DOWNLOADS:
|
pass
|
||||||
if host_os == download.get("type"):
|
|
||||||
logger.info(f"Monkey exec found for os: {host_os}")
|
|
||||||
return download
|
|
||||||
logger.warning(f"No monkey executables could be found for the host os: {host_os}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class MonkeyDownload(flask_restful.Resource):
|
class MonkeyDownload(flask_restful.Resource):
|
||||||
|
|
||||||
# Used by monkey. can't secure.
|
# Used by monkey. can't secure.
|
||||||
def get(self, path):
|
def get(self, host_os):
|
||||||
return send_from_directory(os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", "binaries"), path)
|
try:
|
||||||
|
path = get_agent_executable_path(host_os)
|
||||||
# Used by monkey. can't secure.
|
return send_from_directory(path.parent, path.name)
|
||||||
def post(self):
|
except UnsupportedOSError as ex:
|
||||||
host_json = json.loads(request.data)
|
logger.error(ex)
|
||||||
host_os = host_json.get("os")
|
return make_response({"error": str(ex)}, 404)
|
||||||
if host_os:
|
|
||||||
result = get_monkey_executable(host_os.get("type"))
|
|
||||||
|
|
||||||
if result:
|
|
||||||
# change resulting from new base path
|
|
||||||
executable_filename = result["filename"]
|
|
||||||
real_path = MonkeyDownload.get_executable_full_path(executable_filename)
|
|
||||||
if os.path.isfile(real_path):
|
|
||||||
result["size"] = os.path.getsize(real_path)
|
|
||||||
return result
|
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_executable_full_path(executable_filename):
|
|
||||||
real_path = os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", "binaries", executable_filename)
|
|
||||||
return real_path
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def log_executable_hashes():
|
def log_executable_hashes():
|
||||||
|
@ -65,16 +36,30 @@ class MonkeyDownload(flask_restful.Resource):
|
||||||
Logs all the hashes of the monkey executables for debugging ease (can check what Monkey
|
Logs all the hashes of the monkey executables for debugging ease (can check what Monkey
|
||||||
version you have etc.).
|
version you have etc.).
|
||||||
"""
|
"""
|
||||||
filenames = set([x["filename"] for x in MONKEY_DOWNLOADS])
|
filenames = set(AGENTS.values())
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
filepath = MonkeyDownload.get_executable_full_path(filename)
|
filepath = get_executable_full_path(filename)
|
||||||
if os.path.isfile(filepath):
|
if filepath.is_file():
|
||||||
with open(filepath, "rb") as monkey_exec_file:
|
with open(filepath, "rb") as monkey_exec_file:
|
||||||
file_contents = monkey_exec_file.read()
|
file_contents = monkey_exec_file.read()
|
||||||
logger.debug(
|
file_sha256_hash = filename, hashlib.sha256(file_contents).hexdigest()
|
||||||
"{} hashes:\nSHA-256 {}".format(
|
logger.debug(f"{filename} hash:\nSHA-256 {file_sha256_hash}")
|
||||||
filename, hashlib.sha256(file_contents).hexdigest()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
logger.debug("No monkey executable for {}.".format(filepath))
|
logger.debug(f"No monkey executable for {filepath}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_agent_executable_path(host_os: str) -> Path:
|
||||||
|
try:
|
||||||
|
agent_path = get_executable_full_path(AGENTS[host_os])
|
||||||
|
logger.debug(f"Monkey exec found for os: {host_os}, {agent_path}")
|
||||||
|
|
||||||
|
return agent_path
|
||||||
|
except KeyError:
|
||||||
|
logger.warning(f"No monkey executables could be found for the host os: {host_os}")
|
||||||
|
raise UnsupportedOSError(
|
||||||
|
f'No Agents are available for unsupported operating system "{host_os}"'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_executable_full_path(executable_filename: str) -> Path:
|
||||||
|
return Path(MONKEY_ISLAND_ABS_PATH) / "cc" / "binaries" / executable_filename
|
||||||
|
|
|
@ -5,8 +5,8 @@ import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
|
|
||||||
from monkey_island.cc.resources.monkey_download import get_monkey_executable
|
from monkey_island.cc.resources.monkey_download import get_agent_executable_path
|
||||||
from monkey_island.cc.server_utils.consts import ISLAND_PORT, MONKEY_ISLAND_ABS_PATH
|
from monkey_island.cc.server_utils.consts import ISLAND_PORT
|
||||||
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
from monkey_island.cc.services.utils.network_utils import local_ip_addresses
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -25,12 +25,13 @@ class LocalMonkeyRunService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def run_local_monkey():
|
def run_local_monkey():
|
||||||
# get the monkey executable suitable to run on the server
|
# get the monkey executable suitable to run on the server
|
||||||
result = get_monkey_executable(platform.system().lower())
|
try:
|
||||||
if not result:
|
src_path = get_agent_executable_path(platform.system().lower())
|
||||||
return False, "OS Type not found"
|
except Exception as ex:
|
||||||
|
logger.error(f"Error running agent from island: {ex}")
|
||||||
|
return False, str(ex)
|
||||||
|
|
||||||
src_path = os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", "binaries", result["filename"])
|
dest_path = LocalMonkeyRunService.DATA_DIR / src_path.name
|
||||||
dest_path = os.path.join(LocalMonkeyRunService.DATA_DIR, result["filename"])
|
|
||||||
|
|
||||||
# copy the executable to temp path (don't run the monkey from its current location as it may
|
# copy the executable to temp path (don't run the monkey from its current location as it may
|
||||||
# delete itself)
|
# delete itself)
|
||||||
|
|
Loading…
Reference in New Issue