The Praetorian CLI has a scripting engine for you to easily extend the CLI in just a few steps. The walkthrough below is based on the documentation here.

First step, set the `PRAETORIAN_SCRIPTS_PATH` environment variable to point to
the directory where you will store your scripting code. 

To set the environmental variable for your session, you can enter the following:

export PRAETORIAN_SCRIPTS_PATH=~/your/cli-scripts/path

If you want to permanently set that PRAETORIAN_SCRIPTS_PATH environment variable, you can add the above line to your shell configuration file.

The CLI attempts to load every .py file from that directory with the register() function defined. All compatible scripts will be added to the script group in the CLI. You can check whether your script was loaded with:

praetorian chariot script --help

The code snippet below is a concrete example that runs an nmap scan on a host and adds the open ports found in the scan to Chariot using the SDK.

The main logic is in `nmap_command`. This function uses Click decorators to register itself
to the CLI and define command line arguments.

Equally important is the register() function. It must take one argument script_group and
use the add_command function to register the nmap_command function with the CLI.

@click.command('nmap')
@click.argument('host', required=True)
@cli_handler
def nmap_command(sdk, host):
""" An nmap script for scanning a host.

HOST is the host you want to scan. It can be a hostname or an IP address.
"""

print(f'Running nmap on {host}...')
result = subprocess.run(['nmap', '-p22,80,443', host], capture_output=True, text=True)

if 'Nmap scan report' in result.stdout:
lines = result.stdout.split('\n')
asset_key = f'#asset#{host}#{host}.'
sdk.add('asset', dict(name=host, dns=host))
print(f'Added asset {asset_key}')
for l in lines[5:]:
match = re.match('^(\d+)/[a-z]+\s+open\s+([a-z]+)$', l)
if match:
(port, protocol) = match.groups()
sdk.add('attribute', dict(key=asset_key, name=protocol, value=port))
print(f'Added attribute for open port {port} running {protocol}.')
else:
print("No live host found.")


def register(script_group: click.MultiCommand):
script_group.add_command(nmap_command)

The full example script with comments and notes is available here: nmap-example.py.

Debugging

The CLI skips loading scripts that have compilation errors. If you script does not appear in praetorian chariot script --help, run the CLI with the --debug flag to see the compilation errors.

Good luck creating your own script and extending the value of Praetorian-CLI and Chariot!

Note: Scripts are only supported in Linux and macOS systems.

 

If you find a topic that you would like discussed in detail, or need further assistance, please let us know at support@praetorian.com!