> For the complete documentation index, see [llms.txt](https://docs.enginsight.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.enginsight.com/docs/knowledge-base/english/penetration-tests/how-can-i-use-custom-scripts-in-penetration-tests-with-enginsight.md).

# How can I use custom scripts in penetration tests with Enginsight?

A penetration test is a planned and controlled automated attack on your own systems that is used to identify vulnerabilities in a targeted way. Penetration tests are performed using the Enginsight component Hacktor.

Enginsight provides an extensive library of checks for this purpose, which you can extend with custom scripts. These scripts are stored directly on the Linux server on which Hacktor is installed.

In the following, we will show you how to create custom scripts for penetration tests and make them available in the Enginsight platform.

***

## Adding a Custom Script

{% hint style="warning" %}
**Please note**: To create custom scripts and use them in the Enginsight platform, you need administrator rights for the server on which the Hacktor component is installed.
{% endhint %}

Follow these steps to add your own script for penetration tests:

{% stepper %}
{% step %}

### Navigate to the script folder

Log in to the Linux server on which the Hacktor that should execute the custom script is installed.

Navigate to the **scripts** folder using the following command:

```
cd /opt/enginsight/hacktor/scripts
```

{% endstep %}

{% step %}

### Create the script file

Create a file for the custom script using the following command:

```
sudo nano <RuntimeEnvironment>_<Severity>_<ScriptName>.<FileExtension>
```

The file name must follow this pattern: `<RuntimeEnvironment>_<Severity>_<ScriptName>.<FileExtension>`

Replace the placeholders in `<>` as follows:

<table><thead><tr><th width="202.37890625">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>&#x3C;RuntimeEnvironment></code></td><td><p>Specify the runtime environment you want to use for your script.<br></p><p>The following runtime environments are supported:</p><ul><li>bash</li><li>python2</li><li>python3</li><li>ruby</li></ul></td></tr><tr><td><code>&#x3C;Severity></code></td><td><p>Specify the severity level or criticality that should be displayed if the check defined in the script fails.</p><p><br>The following severity levels are supported:</p><ul><li>ok</li><li>low</li><li>medium</li><li>high</li><li>critical</li></ul></td></tr><tr><td><code>&#x3C;ScriptName></code></td><td>Define a custom script name for your script.</td></tr><tr><td><code>&#x3C;FileExtension></code></td><td>Enter the file extension that matches the selected runtime environment, that is, <strong>.sh</strong> for Bash scripts, <strong>.py</strong> for Python scripts and <strong>.rb</strong> for Ruby scripts.</td></tr></tbody></table>

Example: `python2_critical_mycustomscript.py`
{% endstep %}

{% step %}

### Insert and save the script

1. Now insert your own script. It must be created according to the [custom script guidelines](#guidelines-for-custom-scripts). [Script examples](#examples-for-different-scripting-languages) for the different runtime environments are provided below.
2. Save the file (**Ctrl** + **o**) and confirm the save process. Close the file (**Ctrl** + **x**).
   {% endstep %}

{% step %}

### Make the script file available to Hacktor

Now use the following command to ensure that Hacktor can access and execute the newly created script file:

```
chmod 755 <FileName>
```

Here, `<FileName>` corresponds to the name you created in [step 2](#create-the-script-file).
{% endstep %}

{% step %}

### Restart Hacktor

Restart Hacktor using the following command to apply the configuration changes:

```
sudo systemctl restart ngs-hacktor
```

{% endstep %}

{% step %}

### Check the advanced settings

Log in to the Enginsight platform and navigate to **Penetration Testing** → **Audit Definitions**.

<i class="fa-computer-mouse">:computer-mouse:</i> Click <i class="fa-plus">:plus:</i> **Create Audit Definition** in the upper-right corner of the audit overview to [add a new audit definition](https://docs.enginsight.com/docs/manual/english/platform-usage/penetration-testing/management/audit-definitions/add-audit-definition), or edit an existing audit definition.

<i class="fa-computer-mouse">:computer-mouse:</i> Click **Advanced Settings** and make sure that the checkbox <i class="fa-square-check">:square-check:</i> next to the **Execute custom scripts** option is enabled.
{% endstep %}
{% endstepper %}

***

## Guidelines for Custom Scripts

The following guidelines apply to creating custom scripts, regardless of the scripting language used:

### Arguments

Argument 1 must always be the **hostname**. Arguments 2-n must be the **open ports** required to execute the script.

### Exit Code

For Hacktor to be able to read the result of the check performed by the script, you must follow these conventions for the exit status code:

<table><thead><tr><th width="164.13411458333331">Status</th><th width="128.51953125">Exit code</th><th>Description</th></tr></thead><tbody><tr><td>Passed</td><td>0</td><td>The check was passed.</td></tr><tr><td>Error</td><td>1</td><td>The check did not work.</td></tr><tr><td>Skipped</td><td>5</td><td>The check is irrelevant for the target system.</td></tr><tr><td>Failed</td><td>9</td><td>The check failed. The target system is vulnerable.</td></tr></tbody></table>

{% hint style="info" %}
**Please note**: Any other exit code is treated as the **Error** status.
{% endhint %}

Regardless of the check result, the standard output `stdout` and error output `stderr` are shown in the audit. Output is truncated after 1024 characters.

***

## Examples for Different Scripting Languages

### Python2 and Python3

```
import sys

print("Host:",sys.argv[1])
print("Ports:",sys.argv[2:])

print("Use 'sys.exit(1)' with error codes (1=error, 5=skipped, 9=failed) to determine check status")

sys.exit(9)
```

#### Example Python Script for a Custom Check

```
import socket
import sys

# This is an example script
# It checks if a host uses an OpenSSH implementation

host = sys.argv[1]
ports = sys.argv[2:]

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

if '22' in ports:

    addr = (host, 22)

    try:
        sock.connect(addr)
    except:
       print >>sys.stderr, 'failed to connect'
       sys.exit(1) # check has 'error' status

    try:
        message = 'SSH-2.0-Hacktor'
        sock.sendall(message)
   
        data = sock.recv(256)
        print >>sys.stdout, "Banner: %s" % data

        if 'OpenSSH' in data:
            print >>sys.stdout, "Host uses OpenSSH implementation"
            sock.close()
            sys.exit(0)

        else:
            print >>sys.stdout, "Host does not use OpenSSH implementation."
            sock.close()
            sys.exit(9) # check is 'failed'

    finally:
        sock.close()

else:
    print >>sys.stdout, 'host %s does not use port 22' % host
    sys.exit(5) # check is 'skipped'
```

### Ruby

```
puts "Host: "+ARGV[0]
puts "Ports: "+ARGV.inspect[0..-1]

puts "Use 'exit(1)' with error codes (1=error, 5=skipped, 9=failed) to determine check status"
```

### Bash

```
#!/bin/bash

echo "Host: $1"

shift # remove the first argument
echo "Shift. Then Ports:" "$@"

exit 5 # Use 'exit 1' with error codes (1=error, 5=skipped, 9=failed) to determine check status
```

***

## Optional: Custom Title and Recommendation Text for the Check

Optionally, you can define a custom title for the check you have created using the custom script. In the audit, this replaces the title you specified in the file name earlier in [step 2](#create-the-script-file). You can also add a recommendation describing how to address a detected vulnerability.

Follow these steps:

{% stepper %}
{% step %}

### Open the description file

1. Log in to the Linux server on which you stored the custom script or scripts.
2. Open the **description.json** file using the following command:

```
sudo nano /opt/enginsight/hacktor/scripts/descriptions.json
```

{% endstep %}

{% step %}

### Add title and recommendation

1. Now add the title and recommendation using the following pattern:

```
{
    "<FileNameA>":{
        "title":"<CustomCheckTitle>",
        "recommendation":"<RemediationRecommendation>"
    },
    "<FileNameB>":{
        "title":"<CustomCheckTitle>",
        "recommendation":"<RemediationRecommendation>"
    }
```

Replace the placeholders in `<>` as follows:

<table><thead><tr><th width="258.9921875">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><code>&#x3C;FileNameA></code></td><td>Enter the file name you defined earlier in <a href="#create-the-script-file">step 2</a>.</td></tr><tr><td><code>&#x3C;CustomCheckTitle></code></td><td>Define a custom title for the check that should be displayed in the platform.</td></tr><tr><td><code>&#x3C;RemediationRecommendation></code></td><td>Enter a recommendation on how to remediate the vulnerability checked by the script.</td></tr></tbody></table>

2. Save the file (**Ctrl** + **o**) and confirm the save process. Close the file (**Ctrl** + **x**).
   {% endstep %}

{% step %}

### Restart Hacktor

Restart Hacktor using the following command to apply the changes:

```
sudo systemctl restart ngs-hacktor
```

{% endstep %}
{% endstepper %}

***
