forked from p15670423/monkey
Merge pull request #1804 from guardicore/1782-powershell
Agent: Upload binary with random string when using powershell
This commit is contained in:
commit
82b6cdbad5
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
from pathlib import Path
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from infection_monkey.exploit.HostExploiter import HostExploiter
|
from infection_monkey.exploit.HostExploiter import HostExploiter
|
||||||
|
@ -19,7 +19,7 @@ from infection_monkey.exploit.powershell_utils.powershell_client import (
|
||||||
IPowerShellClient,
|
IPowerShellClient,
|
||||||
PowerShellClient,
|
PowerShellClient,
|
||||||
)
|
)
|
||||||
from infection_monkey.exploit.tools.helpers import get_random_file_suffix
|
from infection_monkey.exploit.tools.helpers import get_agent_dest_path, get_random_file_suffix
|
||||||
from infection_monkey.model import DROPPER_ARG, RUN_MONKEY, VictimHost
|
from infection_monkey.model import DROPPER_ARG, RUN_MONKEY, VictimHost
|
||||||
from infection_monkey.utils.commands import build_monkey_commandline
|
from infection_monkey.utils.commands import build_monkey_commandline
|
||||||
from infection_monkey.utils.environment import is_windows_os
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
@ -170,7 +170,7 @@ class PowerShellExploiter(HostExploiter):
|
||||||
raise ValueError(f"Unknown secret type {credentials.secret_type}")
|
raise ValueError(f"Unknown secret type {credentials.secret_type}")
|
||||||
|
|
||||||
def _execute_monkey_agent_on_victim(self):
|
def _execute_monkey_agent_on_victim(self):
|
||||||
monkey_path_on_victim = self.options["dropper_target_path_win_64"]
|
monkey_path_on_victim = get_agent_dest_path(self.host, self.options)
|
||||||
|
|
||||||
self._copy_monkey_binary_to_victim(monkey_path_on_victim)
|
self._copy_monkey_binary_to_victim(monkey_path_on_victim)
|
||||||
logger.info("Successfully copied the monkey binary to the victim.")
|
logger.info("Successfully copied the monkey binary to the victim.")
|
||||||
|
@ -182,9 +182,9 @@ class PowerShellExploiter(HostExploiter):
|
||||||
f"Failed to execute the agent binary on the victim: {ex}"
|
f"Failed to execute the agent binary on the victim: {ex}"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _copy_monkey_binary_to_victim(self, monkey_path_on_victim):
|
def _copy_monkey_binary_to_victim(self, monkey_path_on_victim: Path):
|
||||||
|
|
||||||
temp_monkey_binary_filepath = f"monkey_temp_bin_{get_random_file_suffix()}"
|
temp_monkey_binary_filepath = Path(f"./monkey_temp_bin_{get_random_file_suffix()}")
|
||||||
|
|
||||||
self._create_local_agent_file(temp_monkey_binary_filepath)
|
self._create_local_agent_file(temp_monkey_binary_filepath)
|
||||||
|
|
||||||
|
@ -194,8 +194,8 @@ class PowerShellExploiter(HostExploiter):
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
raise RemoteAgentCopyError(f"Failed to copy the agent binary to the victim: {ex}")
|
raise RemoteAgentCopyError(f"Failed to copy the agent binary to the victim: {ex}")
|
||||||
finally:
|
finally:
|
||||||
if os.path.isfile(temp_monkey_binary_filepath):
|
if temp_monkey_binary_filepath.is_file():
|
||||||
os.remove(temp_monkey_binary_filepath)
|
temp_monkey_binary_filepath.unlink()
|
||||||
|
|
||||||
def _create_local_agent_file(self, binary_path):
|
def _create_local_agent_file(self, binary_path):
|
||||||
agent_binary_bytes = self.agent_repository.get_agent_binary("windows")
|
agent_binary_bytes = self.agent_repository.get_agent_binary("windows")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import abc
|
import abc
|
||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import pypsrp
|
import pypsrp
|
||||||
|
@ -63,7 +64,7 @@ class IPowerShellClient(Protocol, metaclass=abc.ABCMeta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def copy_file(self, src: str, dest: str) -> bool:
|
def copy_file(self, src: Path, dest: Path) -> bool:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -101,9 +102,9 @@ class PowerShellClient(IPowerShellClient):
|
||||||
output, _, _ = self._client.execute_cmd(cmd)
|
output, _, _ = self._client.execute_cmd(cmd)
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def copy_file(self, src: str, dest: str):
|
def copy_file(self, src: Path, dest: Path):
|
||||||
try:
|
try:
|
||||||
self._client.copy(src, dest)
|
self._client.copy(str(src), str(dest))
|
||||||
logger.debug(f"Successfully copied {src} to {dest} on {self._ip_addr}")
|
logger.debug(f"Successfully copied {src} to {dest} on {self._ip_addr}")
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error(f"Failed to copy {src} to {dest} on {self._ip_addr}: {ex}")
|
logger.error(f"Failed to copy {src} to {dest} on {self._ip_addr}: {ex}")
|
||||||
|
|
|
@ -26,6 +26,9 @@ class AuthenticationErrorForTests(Exception):
|
||||||
mock_agent_repository = MagicMock()
|
mock_agent_repository = MagicMock()
|
||||||
mock_agent_repository.get_agent_binary.return_value = BytesIO(b"BINARY_EXECUTABLE")
|
mock_agent_repository.get_agent_binary.return_value = BytesIO(b"BINARY_EXECUTABLE")
|
||||||
|
|
||||||
|
victim_host = VictimHost("127.0.0.1")
|
||||||
|
victim_host.os["type"] = "windows"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def powershell_arguments():
|
def powershell_arguments():
|
||||||
|
@ -39,7 +42,7 @@ def powershell_arguments():
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
arguments = {
|
arguments = {
|
||||||
"host": VictimHost("127.0.0.1"),
|
"host": victim_host,
|
||||||
"options": options,
|
"options": options,
|
||||||
"current_depth": 2,
|
"current_depth": 2,
|
||||||
"telemetry_messenger": MagicMock(),
|
"telemetry_messenger": MagicMock(),
|
||||||
|
@ -141,7 +144,7 @@ def test_successful_copy(monkeypatch, powershell_exploiter, powershell_arguments
|
||||||
|
|
||||||
exploit_result = powershell_exploiter.exploit_host(**powershell_arguments)
|
exploit_result = powershell_exploiter.exploit_host(**powershell_arguments)
|
||||||
|
|
||||||
assert DROPPER_TARGET_PATH_64 in mock_client.return_value.copy_file.call_args[0][1]
|
assert DROPPER_TARGET_PATH_64 in str(mock_client.return_value.copy_file.call_args[0][1])
|
||||||
assert exploit_result.exploitation_success
|
assert exploit_result.exploitation_success
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue