Skip to content
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
7 changes: 7 additions & 0 deletions docs/administration/enterprise.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ according to the [OpenAEV architecture](../deployment/platform/overview.md#archi
The SentinelOne Agent can be leveraged to execute implants as detached processes that will then execute payloads
according to the [OpenAEV architecture](../deployment/platform/overview.md#architecture)

### Palo Alto Cortex Agent

The Palo Alto Cortex Agent can be leveraged to execute implants as detached processes that will then execute payloads
according to the [OpenAEV architecture](../deployment/platform/overview.md#architecture).

On Windows, because Palo Alto Cortex whitelists its own process tree, OpenAEV creates a scheduled task to detach the process that will execute the payloads.

## Remediations in CVES

More detail: [CVES](taxonomies.md) and [Findings view](../usage/findings.md)
Expand Down
Binary file added docs/deployment/assets/paloaltocortex-agents.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/deployment/assets/paloaltocortex-scripts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions docs/deployment/assets/paloaltocortex_subprocessor_unix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import os

def run(command):
exit_code = os.system("echo " + command + " | base64 -d | sh")
print("Exit code:", exit_code)

if __name__ == "__main__":
run(command)
155 changes: 155 additions & 0 deletions docs/deployment/assets/paloaltocortex_subprocessor_windows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import os
import subprocess
import sys
import traceback
import ctypes
import re

PtyProcess = None
try:
from winpty import PtyProcess
except:
PtyProcess = None


def ensure_console():
"""Ensure the current process has a valid console.

When launched from Palo Alto's agent, the process may not have
a console attached, which causes child processes (especially cmd.exe)
to fail when they try to inherit console handles.
"""
kernel32 = ctypes.windll.kernel32
if not kernel32.AttachConsole(-1):
kernel32.AllocConsole()
hwnd = kernel32.GetConsoleWindow()
if hwnd:
ctypes.windll.user32.ShowWindow(hwnd, 0)


def remove_control_characters(text):
"""Remove all the control characters from a string"""
text = re.sub(r"\x1b\[\??(\d;?)*\w", '', text)
text = re.sub(r"\x1b\]0;.*\x07", '\r\n', text)
text = re.sub("\r\n>> ", '', text)
return text


def remove_leading_cmd(text):
"""Removes leading "cmd" or "cmd.exe" from the text if present.

:param text: a string
:type text: str
:rtype: str
"""
if text.startswith("cmd.exe"):
return text[7:]
elif text.startswith("cmd"):
return text[3:]
return text


def is_direct_executable(command):
"""Check if the command starts with a known executable."""
first_token = command.strip().split()[0].lower()
return first_token in [
"powershell.exe", "powershell",
"cmd.exe", "cmd",
"pwsh.exe", "pwsh"
]


def run(commands_list):
"""Runs a list of commands via winpty, falling back to subprocess.

:param commands_list: list of commands
:type commands_list: list
:return: commands output dict - {<command>: <output>}
:rtype: dict
"""
ensure_console()

result = {}
for command in commands_list:
sys.stdout.write(f"Running command <{command[:100]}>...\n")
args = command
try:
env = os.environ.copy()

if 'COMSPEC' not in env:
env['COMSPEC'] = os.path.expandvars("%SYSTEMROOT%\\System32\\cmd.exe")
if 'SystemRoot' not in env:
env['SystemRoot'] = os.environ.get('SystemRoot', 'C:\\Windows')

if is_direct_executable(command):
# Direct executable call (e.g., powershell.exe -encodedCommand ...)
# Run without shell wrapping or winpty
with subprocess.Popen(
args=args,
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
) as process:
stdout, stderr = process.communicate(timeout=300)
if stderr:
sys.stderr.write(f"stderr: \n{stderr.decode('utf-8', errors='replace')}\n")
if stdout:
sys.stdout.write(f"stdout: \n{stdout.decode('utf-8', errors='replace')}\n")
result[command] = stdout.decode('utf-8', errors='replace').splitlines()
else:
result[command] = None
elif PtyProcess:
command = remove_leading_cmd(command)
command_prompt_path = os.path.expandvars("%SYSTEMROOT%\\System32\\cmd.exe")
proc = PtyProcess.spawn(command_prompt_path, cwd="c:\\")
proc.write("cls\r\n")
proc.read()
proc.write(command + '\r\n')
proc.write('exit\r\n')
stdout = ""
while proc.isalive():
buff = proc.read(32768)
stdout += buff
if proc.eof():
break
sys.stdout.write(f"stdout: {stdout}")
stdout = remove_control_characters(stdout)
stdout = stdout.split(command, 1)[1]
stdout = stdout.split(":\\>exit", 1)[0][:-1]
lines = stdout.split("\r\n")
lines = [line.strip() for line in lines if line.strip()]
result[command] = lines
proc.terminate()
else:
sys.stderr.write(
"WARNING: winpty not available, falling back to subprocess\n"
)
with subprocess.Popen(
args=args,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
creationflags=subprocess.CREATE_NEW_CONSOLE,
) as process:
stdout, stderr = process.communicate(timeout=300)
if stderr:
sys.stderr.write(f"stderr: \n{stderr.decode('utf-8', errors='replace')}\n")
if stdout:
sys.stdout.write(f"stdout: \n{stdout.decode('utf-8', errors='replace')}\n")
result[command] = stdout.decode('utf-8', errors='replace').splitlines()
else:
result[command] = None
except subprocess.TimeoutExpired:
sys.stderr.write(f"Command timed out: <{command[:100]}>...\n")
result[command] = None
except Exception:
sys.stderr.write(f"Failed open command: <{command[:100]}>, error: {traceback.format_exc()}")

return result


if __name__ == '__main__':
results = run(commands_list)
File renamed without changes.
File renamed without changes.
104 changes: 99 additions & 5 deletions docs/deployment/ecosystem/executors.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ architectures. This table below summarizes the information about each agent.
| **Tanium Agent** | Under license | As a system service | Executable | An admin background process | As a system admin | No, always the same agent |
| **Crowdstrike Falcon Agent** | Under license | As a system service | Executable | An admin background process | As a system admin | No, always the same agent |
| **SentinelOne Agent** | Under license | As a system service | Executable | An admin background process | As a system admin | No, always the same agent |
| **Palo Alto Cortex Agent** | Under license | As a system service | Executable | An admin background process | As a system admin | No, always the same agent |
| **Caldera Agent** | Open source | As a user session | Script | An admin background process | As a user admin | Yes, depending on the user |

## OpenAEV Agent
Expand Down Expand Up @@ -79,7 +80,7 @@ Once configured and imported, retrieve the package IDs from the URL:

### Configure the OpenAEV Platform

To use the Tanium executor, fill the following configuration:
To use the Tanium executor, fill the following configuration in the Integrations (Executors) tab from OpenAEV menu.

| Parameter | Environment variable | Default value | Description |
|:------------------------------------------------------|:------------------------------------------------------|:---------------|:--------------------------------------------------------------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -257,7 +258,7 @@ applied.

Please note that the CrowdStrike API key should have the following permissions: API integrations, Hosts, Host groups, Real time response.

To use the CrowdStrike executor, just fill the following configuration.
To use the CrowdStrike executor, just fill the following configuration in the Integrations (Executors) tab from OpenAEV menu.

| Parameter | Environment variable | Default value | Description |
|:-----------------------------------------------------------|:------------------------------------------------------------|:-----------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -291,6 +292,99 @@ Endpoint on the OpenAEV endpoint page.

You are now ready to leverage your CrowdStrike platform to run OpenAEV payloads!

---
<a id="paloaltocortex-agent"></a>
## Palo Alto Cortex Agent

The Palo Alto Cortex agent can be leveraged to execute implants as detached processes that will then execute payloads
according to the [OpenAEV architecture](https://docs.openaev.io/latest/deployment/overview).

On Windows, because Palo Alto Cortex whitelists its own process tree, OpenAEV creates a scheduled task to detach the process that will execute the payloads.

The implants will be downloaded to these folders on the different assets:

* On Windows assets: `C:\Program Files (x86)\Filigran\OAEV Agent\runtimes\implant-XXXXX`
* On Linux or MacOS assets: `/opt/openaev-agent/runtimes/implant-XXXXX`

where XXXXX will be a completely random UUID, generated for each inject that will be executed.
This ensures that the implants are unique and will be deleted on assets' restart.

### Configure the Palo Alto Cortex Platform

#### Upload OpenAEV scripts

First of all, you need to create one custom script for Unix, covering both Linux and MacOS systems and another one for Windows.

To create these scripts, go to `Investigation & responses` > `Action Center` > `Agent Script Library` > `+ New Script`. The names
of the scripts can be changed if necessary, the ids will be put in the OpenAEV configuration.
To get the scripts IDs, it may be necessary to add the Script UID column to the scripts list view.

*Unix Script*

Upload the following Python script:

[Download](../assets/paloaltocortex_subprocessor_unix.py)

Put the following Input schema:

![Palo Alto Cortex unix script1](../assets/paloaltocortex-unix-script-general.png)
![Palo Alto Cortex unix script2](../assets/paloaltocortex-unix-script-inputs-outputs.png)

*Windows script*

Upload the following Python script:

[Download](../assets/paloaltocortex_subprocessor_windows.py)

Put the following Input schema:

![Palo Alto Cortex windows script1](../assets/paloaltocortex-windows-script-general.png)
![Palo Alto Cortex windows script2](../assets/paloaltocortex-windows-script-inputs-outputs.png)

#### Create a group with your targeted assets

To create a group, go to `Inventory` > `Endpoints` > `Groups`.

### Configure the OpenAEV platform

!!! warning "Palo Alto Cortex API Key"

Please note that the Palo Alto Cortex API key created in "Settings/Configurations/API Keys" should have the following minimum role: “Instance Administrator” and security level: "Standard".

To use the Palo Alto Cortex executor, just fill the following configuration in the Integrations (Executors) tab from OpenAEV menu.

| Parameter | Environment variable | Default value | Description |
|:--------------------------------------------------------------|:--------------------------------------------------------------|:--------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| executor.paloaltocortex.enable | EXECUTOR_PALOALTOCORTEX_ENABLE | `false` | Enable the Palo Alto Cortex executor |
| executor.paloaltocortex.url | EXECUTOR_PALOALTOCORTEX_URL | | Palo Alto Cortex URL, the API version used is the v1 |
| executor.paloaltocortex.api-register-interval | EXECUTOR_PALOALTOCORTEX_API_REGISTER_INTERVAL | 1200 | Palo Alto Cortex API interval to register/update the accounts/sites/groups/agents in OpenAEV (in seconds) |
| executor.paloaltocortex.api-batch-execution-action-pagination | EXECUTOR_PALOALTOCORTEX_API_BATCH_EXECUTION_ACTION_PAGINATION | 100 | Palo Alto Cortex API pagination per 5 seconds to set for endpoints batch executions (number of endpoints sent per 5 seconds to Palo Alto Cortex to execute a payload) |
| executor.paloaltocortex.clean-implant-interval | EXECUTOR_PALOALTOCORTEX_CLEAN_IMPLANT_INTERVAL | 8 | Palo Alto Cortex clean old implant interval (in hours) |
| executor.paloaltocortex.api-key-id | EXECUTOR_PALOALTOCORTEX_API_KEY_ID | | Palo Alto Cortex API key id |
| executor.paloaltocortex.api-key | EXECUTOR_PALOALTOCORTEX_API_KEY | | Palo Alto Cortex API key |
| executor.paloaltocortex.group-name | EXECUTOR_PALOALTOCORTEX_GROUP_ID | | Palo Alto Cortex group name or groups names separated with commas |
| executor.paloaltocortex.windows-script-uid | EXECUTOR_PALOALTOCORTEX_WINDOWS_SCRIPT_UID | | Uid of the OpenAEV Palo Alto Cortex Windows script |
| executor.paloaltocortex.unix-script-uid | EXECUTOR_PALOALTOCORTEX_UNIX_SCRIPT_UID | | Uid of the OpenAEV Palo Alto Cortex Unix script |

### Checks

Once enabled, you should see Palo Alto Cortex available in your `Install agents` section

![Palo Alto Cortex available agent](../assets/paloaltocortex-agents.png)

Also, the assets and the asset groups in the selected groups should now be available in the endpoints and asset
groups sections in OpenAEV:

![Palo Alto Cortex Endpoints](../assets/paloaltocortex-endpoints.png)

NB : An Asset can only have one Palo Alto Cortex agent installed due to the uniqueness of the MAC address parameters. If you
try to install again a Palo Alto Cortex agent on a platform, it will overwrite the actual one and you will always see one
Endpoint on the OpenAEV endpoint page.

!!! success "Installation done"

You are now ready to leverage your Palo Alto Cortex platform to run OpenAEV payloads!

---
<a id="sentinelone-agent"></a>
## SentinelOne Agent
Expand Down Expand Up @@ -325,7 +419,7 @@ of the scripts can be changed if necessary, the ids will be put in the OpenAEV c

Upload the following script (encoded for Unix):

[Download](../assets/openaev_subprocessor_unix.sh)
[Download](../assets/sentinelone_subprocessor_unix.sh)

Put the following Input schema:

Expand All @@ -336,7 +430,7 @@ Put the following Input schema:

Upload the following script (encoded for Windows):

[Download](../assets/openaev_subprocessor_windows.ps1)
[Download](../assets/sentinelone_subprocessor_windows.ps1)

Put the following Input schema:

Expand All @@ -357,7 +451,7 @@ To create a wrapper (account/site/group), go to `Settings` > `Accounts/Sites`.

Please note that the SentinelOne API key created in "Settings/Users/Service Users" should have the following minimum role: “IR Team”. The API key and the scripts must be created for and with the same user and the required account/site.

To use the SentinelOne executor, just fill the following configuration.
To use the SentinelOne executor, just fill the following configuration in the Integrations (Executors) tab from OpenAEV menu.

| Parameter | Environment variable | Default value | Description |
|:-----------------------------------------------------------|:-----------------------------------------------------------|:--------------|:------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand Down
Loading