Island: Combine PropagationCredentials and StolenPropagationCredentials

This commit is contained in:
Mike Salvatore 2022-07-11 14:31:04 -04:00
parent 4a4c4324fb
commit a684b12dc3
5 changed files with 115 additions and 89 deletions

View File

@ -31,9 +31,7 @@ from monkey_island.cc.resources.blackbox.telemetry_blackbox_endpoint import (
from monkey_island.cc.resources.credentials.configured_propagation_credentials import ( from monkey_island.cc.resources.credentials.configured_propagation_credentials import (
ConfiguredPropagationCredentials, ConfiguredPropagationCredentials,
) )
from monkey_island.cc.resources.credentials.stolen_propagation_credentials import ( from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials
StolenPropagationCredentials,
)
from monkey_island.cc.resources.edge import Edge from monkey_island.cc.resources.edge import Edge
from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation from monkey_island.cc.resources.exploitations.manual_exploitation import ManualExploitation
from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation from monkey_island.cc.resources.exploitations.monkey_exploitation import MonkeyExploitation
@ -48,7 +46,6 @@ 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_download import PBAFileDownload
from monkey_island.cc.resources.pba_file_upload import FileUpload from monkey_island.cc.resources.pba_file_upload import FileUpload
from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials
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
@ -192,7 +189,6 @@ def init_restful_endpoints(api: FlaskDIWrapper):
api.add_resource(PropagationCredentials) api.add_resource(PropagationCredentials)
api.add_resource(ConfiguredPropagationCredentials) api.add_resource(ConfiguredPropagationCredentials)
api.add_resource(StolenPropagationCredentials)
api.add_resource(RemoteRun) api.add_resource(RemoteRun)
api.add_resource(VersionUpdate) api.add_resource(VersionUpdate)

View File

@ -1,4 +1,6 @@
from flask import make_response from http import HTTPStatus
from flask import make_response, request
from common.credentials import Credentials from common.credentials import Credentials
from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.repository import ICredentialsRepository
@ -6,12 +8,35 @@ from monkey_island.cc.resources.AbstractResource import AbstractResource
class PropagationCredentials(AbstractResource): class PropagationCredentials(AbstractResource):
urls = ["/api/propagation-credentials"] urls = ["/api/propagation-credentials", "/api/propagation-credentials/stolen-credentials"]
def __init__(self, credentials_repository: ICredentialsRepository): def __init__(self, credentials_repository: ICredentialsRepository):
self._credentials_repository = credentials_repository self._credentials_repository = credentials_repository
def get(self): def get(self):
propagation_credentials = []
if request.url.endswith("/stolen-credentials"):
propagation_credentials = self._credentials_repository.get_stolen_credentials()
else:
propagation_credentials = self._credentials_repository.get_all_credentials() propagation_credentials = self._credentials_repository.get_all_credentials()
return make_response(Credentials.to_json_array(propagation_credentials), 200) return make_response(Credentials.to_json_array(propagation_credentials), HTTPStatus.OK)
def post(self):
credentials = [Credentials.from_json(c) for c in request.json]
if request.url.endswith("/stolen-credentials"):
self._credentials_repository.save_stolen_credentials(credentials)
else:
return {}, HTTPStatus.METHOD_NOT_ALLOWED
return {}, HTTPStatus.NO_CONTENT
def delete(self):
if request.url.endswith("/stolen-credentials"):
self._credentials_repository.remove_stolen_credentials()
else:
return {}, HTTPStatus.METHOD_NOT_ALLOWED
return {}, HTTPStatus.NO_CONTENT

View File

@ -1,28 +0,0 @@
import logging
from flask import jsonify, request
from common.credentials import Credentials
from monkey_island.cc.repository import ICredentialsRepository
from monkey_island.cc.resources.AbstractResource import AbstractResource
logger = logging.getLogger(__name__)
class StolenPropagationCredentials(AbstractResource):
urls = ["/api/propagation-credentials/stolen"]
def __init__(self, credentials_repository: ICredentialsRepository):
self._credentials_repository = credentials_repository
def get(self):
return jsonify(self._credentials_repository.get_stolen_credentials())
def post(self):
credentials = Credentials.from_mapping(request.json)
self._credentials_repository.save_stolen_credentials(credentials)
return {}, 204
def delete(self):
self._credentials_repository.remove_stolen_credentials()
return {}, 204

View File

@ -1,34 +1,110 @@
import json
from http import HTTPStatus
import pytest import pytest
from tests.common import StubDIContainer from tests.common import StubDIContainer
from tests.monkey_island import ( from tests.data_for_tests.propagation_credentials import (
PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_1,
PROPAGATION_CREDENTIALS_2, PROPAGATION_CREDENTIALS_2,
StubPropagationCredentialsRepository, PROPAGATION_CREDENTIALS_3,
PROPAGATION_CREDENTIALS_4,
) )
from tests.unit_tests.monkey_island.conftest import get_url_for_resource from tests.monkey_island import InMemoryCredentialsRepository
from common.credentials import Credentials from common.credentials import Credentials
from monkey_island.cc.repository import ICredentialsRepository from monkey_island.cc.repository import ICredentialsRepository
from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials from monkey_island.cc.resources.credentials.propagation_credentials import PropagationCredentials
ALL_CREDENTIALS_URL = PropagationCredentials.urls[0]
STOLEN_CREDENTIALS_URL = PropagationCredentials.urls[1]
@pytest.fixture @pytest.fixture
def flask_client(build_flask_client): def credentials_repository():
return InMemoryCredentialsRepository()
@pytest.fixture
def flask_client(build_flask_client, credentials_repository):
container = StubDIContainer() container = StubDIContainer()
container.register(ICredentialsRepository, StubPropagationCredentialsRepository) container.register_instance(ICredentialsRepository, credentials_repository)
with build_flask_client(container) as flask_client: with build_flask_client(container) as flask_client:
yield flask_client yield flask_client
def test_propagation_credentials_endpoint_get(flask_client): def test_propagation_credentials_endpoint_get(flask_client, credentials_repository):
propagation_credentials_url = get_url_for_resource(PropagationCredentials) credentials_repository.save_configured_credentials(
[PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_3]
)
credentials_repository.save_stolen_credentials(
[PROPAGATION_CREDENTIALS_2, PROPAGATION_CREDENTIALS_4]
)
resp = flask_client.get(propagation_credentials_url) resp = flask_client.get(ALL_CREDENTIALS_URL)
actual_propagation_credentials = Credentials.from_json_array(resp.text) actual_propagation_credentials = Credentials.from_json_array(resp.text)
assert resp.status_code == 200 assert resp.status_code == HTTPStatus.OK
assert len(actual_propagation_credentials) == 4
assert PROPAGATION_CREDENTIALS_1 in actual_propagation_credentials
assert PROPAGATION_CREDENTIALS_2 in actual_propagation_credentials
assert PROPAGATION_CREDENTIALS_3 in actual_propagation_credentials
assert PROPAGATION_CREDENTIALS_4 in actual_propagation_credentials
def test_propagation_credentials_endpoint__get_stolen(flask_client, credentials_repository):
credentials_repository.save_stolen_credentials(
[PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2]
)
resp = flask_client.get(STOLEN_CREDENTIALS_URL)
actual_propagation_credentials = Credentials.from_json_array(resp.text)
assert resp.status_code == HTTPStatus.OK
assert len(actual_propagation_credentials) == 2 assert len(actual_propagation_credentials) == 2
assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1 assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1
assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2 assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2
def test_propagation_credentials_endpoint__post_stolen(flask_client, credentials_repository):
credentials_repository.save_stolen_credentials([PROPAGATION_CREDENTIALS_1])
resp = flask_client.post(
STOLEN_CREDENTIALS_URL,
json=[
Credentials.to_json(PROPAGATION_CREDENTIALS_2),
Credentials.to_json(PROPAGATION_CREDENTIALS_3),
],
)
assert resp.status_code == HTTPStatus.NO_CONTENT
resp = flask_client.get(STOLEN_CREDENTIALS_URL)
retrieved_propagation_credentials = Credentials.from_json_array(resp.text)
assert resp.status_code == HTTPStatus.OK
assert len(retrieved_propagation_credentials) == 3
assert PROPAGATION_CREDENTIALS_1 in retrieved_propagation_credentials
assert PROPAGATION_CREDENTIALS_2 in retrieved_propagation_credentials
assert PROPAGATION_CREDENTIALS_3 in retrieved_propagation_credentials
def test_stolen_propagation_credentials_endpoint_delete(flask_client, credentials_repository):
credentials_repository.save_stolen_credentials(
[PROPAGATION_CREDENTIALS_1, PROPAGATION_CREDENTIALS_2]
)
resp = flask_client.delete(STOLEN_CREDENTIALS_URL)
assert resp.status_code == HTTPStatus.NO_CONTENT
resp = flask_client.get(STOLEN_CREDENTIALS_URL)
assert len(json.loads(resp.text)) == 0
def test_propagation_credentials_endpoint__propagation_credentials_post_not_allowed(flask_client):
resp = flask_client.post(ALL_CREDENTIALS_URL, json=[])
assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED
def test_propagation_credentials_endpoint__propagation_credentials_delete_not_allowed(flask_client):
resp = flask_client.delete(ALL_CREDENTIALS_URL)
assert resp.status_code == HTTPStatus.METHOD_NOT_ALLOWED

View File

@ -1,43 +0,0 @@
import json
from tests.data_for_tests.propagation_credentials import (
PROPAGATION_CREDENTIALS_1,
PROPAGATION_CREDENTIALS_2,
)
from tests.unit_tests.monkey_island.conftest import get_url_for_resource
from monkey_island.cc.resources.credentials.stolen_propagation_credentials import (
StolenPropagationCredentials,
)
def test_stolen_propagation_credentials_endpoint_get(flask_client):
stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials)
resp = flask_client.get(stolen_propagation_credentials_url)
assert resp.status_code == 200
actual_propagation_credentials = json.loads(resp.data)
assert len(actual_propagation_credentials) == 2
# TODO: delete the removal of monkey_guid key when the serialization of credentials
del actual_propagation_credentials[0]["monkey_guid"]
assert actual_propagation_credentials[0] == PROPAGATION_CREDENTIALS_1
del actual_propagation_credentials[1]["monkey_guid"]
assert actual_propagation_credentials[1] == PROPAGATION_CREDENTIALS_2
def test_stolen_propagation_credentials_endpoint_post(flask_client):
stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials)
resp = flask_client.post(stolen_propagation_credentials_url, json=PROPAGATION_CREDENTIALS_1)
assert resp.status_code == 204
def test_stolen_propagation_credentials_endpoint_delete(flask_client):
stolen_propagation_credentials_url = get_url_for_resource(StolenPropagationCredentials)
resp = flask_client.delete(stolen_propagation_credentials_url)
assert resp.status_code == 204