Merge pull request #2173 from guardicore/2154-refactor-pba-file-upload
2154 refactor pba file upload
This commit is contained in:
commit
34ed72da6b
|
@ -52,6 +52,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- `/api/log/island/download` endpoint to `/api/island/log`. #2107
|
- `/api/log/island/download` endpoint to `/api/island/log`. #2107
|
||||||
- `/api/auth` endpoint to `/api/authenticate`. #2105
|
- `/api/auth` endpoint to `/api/authenticate`. #2105
|
||||||
- `/api/registration` endpoint to `/api/register`. #2105
|
- `/api/registration` endpoint to `/api/register`. #2105
|
||||||
|
- `/api/file-upload` endpoit to `/api/pba/upload`. #2154
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- VSFTPD exploiter. #1533
|
- VSFTPD exploiter. #1533
|
||||||
|
|
|
@ -16,6 +16,8 @@ from monkey_island.cc.resources import (
|
||||||
ClearSimulationData,
|
ClearSimulationData,
|
||||||
IPAddresses,
|
IPAddresses,
|
||||||
IslandLog,
|
IslandLog,
|
||||||
|
PBAFileDownload,
|
||||||
|
PBAFileUpload,
|
||||||
PropagationCredentials,
|
PropagationCredentials,
|
||||||
RemoteRun,
|
RemoteRun,
|
||||||
ResetAgentConfiguration,
|
ResetAgentConfiguration,
|
||||||
|
@ -39,8 +41,6 @@ from monkey_island.cc.resources.monkey import Monkey
|
||||||
from monkey_island.cc.resources.netmap import NetMap
|
from monkey_island.cc.resources.netmap import NetMap
|
||||||
from monkey_island.cc.resources.node import Node
|
from monkey_island.cc.resources.node import Node
|
||||||
from monkey_island.cc.resources.node_states import NodeStates
|
from monkey_island.cc.resources.node_states import NodeStates
|
||||||
from monkey_island.cc.resources.pba_file_download import PBAFileDownload
|
|
||||||
from monkey_island.cc.resources.pba_file_upload import FileUpload
|
|
||||||
from monkey_island.cc.resources.ransomware_report import RansomwareReport
|
from monkey_island.cc.resources.ransomware_report import RansomwareReport
|
||||||
from monkey_island.cc.resources.root import Root
|
from monkey_island.cc.resources.root import Root
|
||||||
from monkey_island.cc.resources.security_report import SecurityReport
|
from monkey_island.cc.resources.security_report import SecurityReport
|
||||||
|
@ -181,7 +181,7 @@ def init_restful_endpoints(api: FlaskDIWrapper):
|
||||||
|
|
||||||
# API Spec: These two should be the same resource, GET for download and POST for upload
|
# API Spec: These two should be the same resource, GET for download and POST for upload
|
||||||
api.add_resource(PBAFileDownload)
|
api.add_resource(PBAFileDownload)
|
||||||
api.add_resource(FileUpload)
|
api.add_resource(PBAFileUpload)
|
||||||
|
|
||||||
api.add_resource(PropagationCredentials)
|
api.add_resource(PropagationCredentials)
|
||||||
api.add_resource(RemoteRun)
|
api.add_resource(RemoteRun)
|
||||||
|
|
|
@ -6,3 +6,5 @@ from .reset_agent_configuration import ResetAgentConfiguration
|
||||||
from .propagation_credentials import PropagationCredentials
|
from .propagation_credentials import PropagationCredentials
|
||||||
from .ip_addresses import IPAddresses
|
from .ip_addresses import IPAddresses
|
||||||
from .agent_configuration import AgentConfiguration
|
from .agent_configuration import AgentConfiguration
|
||||||
|
from .pba_file_upload import PBAFileUpload, LINUX_PBA_TYPE, WINDOWS_PBA_TYPE
|
||||||
|
from .pba_file_download import PBAFileDownload
|
||||||
|
|
|
@ -18,16 +18,15 @@ WINDOWS_PBA_TYPE = "PBAwindows"
|
||||||
|
|
||||||
|
|
||||||
# NOTE: This resource will be reworked when the Custom PBA feature is rebuilt as a payload plugin.
|
# NOTE: This resource will be reworked when the Custom PBA feature is rebuilt as a payload plugin.
|
||||||
class FileUpload(AbstractResource):
|
class PBAFileUpload(AbstractResource):
|
||||||
# API Spec: FileUpload -> PBAFileUpload. Change endpoint accordingly.
|
|
||||||
"""
|
"""
|
||||||
File upload endpoint used to send/receive Custom PBA files
|
File upload endpoint used to send/receive Custom PBA files
|
||||||
"""
|
"""
|
||||||
|
|
||||||
urls = [
|
urls = [
|
||||||
"/api/file-upload/<string:target_os>",
|
"/api/pba/upload/<string:target_os>",
|
||||||
"/api/file-upload/<string:target_os>?load=<string:filename>",
|
"/api/pba/upload/<string:target_os>?load=<string:filename>",
|
||||||
"/api/file-upload/<string:target_os>?restore=<string:filename>",
|
"/api/pba/upload/<string:target_os>?restore=<string:filename>",
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
|
@ -27,8 +27,8 @@ import {
|
||||||
const CONFIG_URL = '/api/agent-configuration';
|
const CONFIG_URL = '/api/agent-configuration';
|
||||||
const RESET_URL = '/api/reset-agent-configuration';
|
const RESET_URL = '/api/reset-agent-configuration';
|
||||||
const CONFIGURED_PROPAGATION_CREDENTIALS_URL = '/api/propagation-credentials/configured-credentials';
|
const CONFIGURED_PROPAGATION_CREDENTIALS_URL = '/api/propagation-credentials/configured-credentials';
|
||||||
export const API_PBA_LINUX = '/api/file-upload/PBAlinux';
|
export const API_PBA_LINUX = '/api/pba/upload/PBAlinux';
|
||||||
export const API_PBA_WINDOWS = '/api/file-upload/PBAwindows';
|
export const API_PBA_WINDOWS = '/api/pba/upload/PBAwindows';
|
||||||
|
|
||||||
const configSubmitAction = 'config-submit';
|
const configSubmitAction = 'config-submit';
|
||||||
const configExportAction = 'config-export';
|
const configExportAction = 'config-export';
|
||||||
|
|
|
@ -4,7 +4,7 @@ from tests.monkey_island import FILE_CONTENTS, FILE_NAME, MockFileRepository
|
||||||
from tests.unit_tests.monkey_island.conftest import get_url_for_resource
|
from tests.unit_tests.monkey_island.conftest import get_url_for_resource
|
||||||
|
|
||||||
from monkey_island.cc.repository import IFileRepository
|
from monkey_island.cc.repository import IFileRepository
|
||||||
from monkey_island.cc.resources.pba_file_download import PBAFileDownload
|
from monkey_island.cc.resources import PBAFileDownload
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
|
@ -9,7 +9,7 @@ from tests.utils import raise_
|
||||||
|
|
||||||
from common import DIContainer
|
from common import DIContainer
|
||||||
from monkey_island.cc.repository import IAgentConfigurationRepository, IFileRepository
|
from monkey_island.cc.repository import IAgentConfigurationRepository, IFileRepository
|
||||||
from monkey_island.cc.resources.pba_file_upload import LINUX_PBA_TYPE, WINDOWS_PBA_TYPE, FileUpload
|
from monkey_island.cc.resources import LINUX_PBA_TYPE, WINDOWS_PBA_TYPE, PBAFileUpload
|
||||||
|
|
||||||
TEST_FILE_CONTENTS = b"m0nk3y"
|
TEST_FILE_CONTENTS = b"m0nk3y"
|
||||||
TEST_FILE = (
|
TEST_FILE = (
|
||||||
|
@ -54,7 +54,7 @@ def flask_client(
|
||||||
|
|
||||||
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
||||||
def test_pba_file_upload_post(flask_client: FlaskClient, pba_os: str):
|
def test_pba_file_upload_post(flask_client: FlaskClient, pba_os: str):
|
||||||
url = get_url_for_resource(FileUpload, target_os=pba_os)
|
url = get_url_for_resource(PBAFileUpload, target_os=pba_os)
|
||||||
resp = flask_client.post(
|
resp = flask_client.post(
|
||||||
url,
|
url,
|
||||||
data=TEST_FILE,
|
data=TEST_FILE,
|
||||||
|
@ -65,7 +65,7 @@ def test_pba_file_upload_post(flask_client: FlaskClient, pba_os: str):
|
||||||
|
|
||||||
|
|
||||||
def test_pba_file_upload_post__invalid(flask_client: FlaskClient):
|
def test_pba_file_upload_post__invalid(flask_client: FlaskClient):
|
||||||
url = get_url_for_resource(FileUpload, target_os="bogus")
|
url = get_url_for_resource(PBAFileUpload, target_os="bogus")
|
||||||
resp = flask_client.post(
|
resp = flask_client.post(
|
||||||
url,
|
url,
|
||||||
data=TEST_FILE,
|
data=TEST_FILE,
|
||||||
|
@ -80,7 +80,7 @@ def test_pba_file_upload_post__internal_server_error(
|
||||||
flask_client: FlaskClient, pba_os: str, file_repository: IFileRepository
|
flask_client: FlaskClient, pba_os: str, file_repository: IFileRepository
|
||||||
):
|
):
|
||||||
file_repository.save_file = lambda x, y: raise_(Exception())
|
file_repository.save_file = lambda x, y: raise_(Exception())
|
||||||
url = get_url_for_resource(FileUpload, target_os=pba_os)
|
url = get_url_for_resource(PBAFileUpload, target_os=pba_os)
|
||||||
|
|
||||||
resp = flask_client.post(
|
resp = flask_client.post(
|
||||||
url,
|
url,
|
||||||
|
@ -93,14 +93,14 @@ def test_pba_file_upload_post__internal_server_error(
|
||||||
|
|
||||||
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
||||||
def test_pba_file_upload_get__file_not_found(flask_client: FlaskClient, pba_os: str):
|
def test_pba_file_upload_get__file_not_found(flask_client: FlaskClient, pba_os: str):
|
||||||
url = get_url_for_resource(FileUpload, target_os=pba_os, filename="bobug_mogus.py")
|
url = get_url_for_resource(PBAFileUpload, target_os=pba_os, filename="bobug_mogus.py")
|
||||||
resp = flask_client.get(url)
|
resp = flask_client.get(url)
|
||||||
assert resp.status_code == 404
|
assert resp.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
||||||
def test_file_download_endpoint_500(open_error_flask_client, pba_os: str):
|
def test_file_download_endpoint_500(open_error_flask_client, pba_os: str):
|
||||||
url = get_url_for_resource(FileUpload, target_os=pba_os, filename="bobug_mogus.py")
|
url = get_url_for_resource(PBAFileUpload, target_os=pba_os, filename="bobug_mogus.py")
|
||||||
|
|
||||||
resp = open_error_flask_client.get(url)
|
resp = open_error_flask_client.get(url)
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ def test_file_download_endpoint_500(open_error_flask_client, pba_os: str):
|
||||||
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
@pytest.mark.parametrize("pba_os", [LINUX_PBA_TYPE, WINDOWS_PBA_TYPE])
|
||||||
def test_pba_file_upload_endpoint(flask_client: FlaskClient, pba_os: str):
|
def test_pba_file_upload_endpoint(flask_client: FlaskClient, pba_os: str):
|
||||||
|
|
||||||
url_with_os = get_url_for_resource(FileUpload, target_os=pba_os)
|
url_with_os = get_url_for_resource(PBAFileUpload, target_os=pba_os)
|
||||||
resp_post = flask_client.post(
|
resp_post = flask_client.post(
|
||||||
url_with_os,
|
url_with_os,
|
||||||
data=TEST_FILE,
|
data=TEST_FILE,
|
||||||
|
@ -118,7 +118,7 @@ def test_pba_file_upload_endpoint(flask_client: FlaskClient, pba_os: str):
|
||||||
follow_redirects=True,
|
follow_redirects=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
url_with_filename = get_url_for_resource(FileUpload, target_os=pba_os, filename="test.py")
|
url_with_filename = get_url_for_resource(PBAFileUpload, target_os=pba_os, filename="test.py")
|
||||||
resp_get = flask_client.get(url_with_filename)
|
resp_get = flask_client.get(url_with_filename)
|
||||||
assert resp_get.status_code == 200
|
assert resp_get.status_code == 200
|
||||||
assert resp_get.data == TEST_FILE_CONTENTS
|
assert resp_get.data == TEST_FILE_CONTENTS
|
||||||
|
@ -135,7 +135,7 @@ def test_pba_file_upload_endpoint(flask_client: FlaskClient, pba_os: str):
|
||||||
|
|
||||||
def test_pba_file_upload_endpoint__invalid(flask_client: FlaskClient):
|
def test_pba_file_upload_endpoint__invalid(flask_client: FlaskClient):
|
||||||
|
|
||||||
url_with_os = get_url_for_resource(FileUpload, target_os="bogus")
|
url_with_os = get_url_for_resource(PBAFileUpload, target_os="bogus")
|
||||||
resp_post = flask_client.post(
|
resp_post = flask_client.post(
|
||||||
url_with_os,
|
url_with_os,
|
||||||
data=TEST_FILE,
|
data=TEST_FILE,
|
||||||
|
@ -144,7 +144,7 @@ def test_pba_file_upload_endpoint__invalid(flask_client: FlaskClient):
|
||||||
)
|
)
|
||||||
|
|
||||||
url_with_filename = get_url_for_resource(
|
url_with_filename = get_url_for_resource(
|
||||||
FileUpload, target_os="bogus", filename="bobug_mogus.py"
|
PBAFileUpload, target_os="bogus", filename="bobug_mogus.py"
|
||||||
)
|
)
|
||||||
resp_get = flask_client.get(url_with_filename)
|
resp_get = flask_client.get(url_with_filename)
|
||||||
resp_delete = flask_client.delete(url_with_os, data="test.py", content_type="text/plain;")
|
resp_delete = flask_client.delete(url_with_os, data="test.py", content_type="text/plain;")
|
||||||
|
|
Loading…
Reference in New Issue