# Custom Scripts

You can add your own scripts to the checks we have included to further extend the functionality of the penetration test. You store the scripts directly on the Linux server on which the Hacktor is installed.

{% hint style="info" %}
To add custom scripts you need administration rights on the server/VM where the Hacktor software component is installed.
{% endhint %}

## Add Custom Script

To add a custom script, follow these steps.

1\. Navigate to the scripts folder.

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

2\. \*\*\*\* Create a file for the custom script. The file name must conform to the following pattern: `<runtime>_<severity>_name.extension,` e.g. `python2_critical_CVE1234.py` or `ruby_ok_my custom script.rb`.

Supported Runtimes:

* `bash`
* `python2`
* `python3`
* `ruby`

Supported Severities:

* `ok`
* `low`
* `medium`
* `high`
* `critical`

```
nano <runtime>_<severity>_name.extension
```

3\. Paste your script that you created according to the [guidelines](https://docs.enginsight.com/docs/master/operation/platform/penetration-testing/..#guidelines-for-custom-scripts).

4\. Save and close the file.

5\. Make your created file executable for Hacktor.

```
chmod 755 <filename>
```

6\. Restart Hacktor.

```
systemctl restart ngs-hacktor
```

## Guidelines for Custom Scripts

To enable Hacktor to read the result of the custom script, the following exit code convention must be followed.

| Status  | Exit Code     | Description                                    |
| ------- | ------------- | ---------------------------------------------- |
| passed  | `exit code 0` | The check is passed.                           |
| error   | `exit code 1` | The check did not work.                        |
| skipped | `exit code 5` | The check is irrelevant for the target system. |
| failed  | `exit code 9` | The target system is vulnerable.               |

Any other exit code is treated as `error`.

Regardless of the check status, `stdout` and `stderr` are output in the audit. Above 1024 characters the output is cropped.

![](https://2429355096-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LTMe1v0eboWCAUTQHbT%2F-MdpkqJukKtV2uDBsbOa%2F-MdplgYxmJRyMo6fdpcf%2Fcoustom_script_stout.png?alt=media\&token=5429511c-b98d-4b1f-b911-0ecb22cc8406)

The first argument is always the `hostname`, the second to n (2-n) are always the open ports.

### Sample

#### python2, 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)
```

```
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 ch
```

## Add your own title and recommendation text

Optionally, you can store your own title, which will replace your title stored in the file name in the audit. You can also store a recommendation on how to deal with the vulnerability.

1\. Open the `descriptions.json` file.

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

Insert the information according to the following pattern:

```
{
    <filenameA>":{
        "title":"<check title>",
        "recommendation":"<recommendation on how to fix>"
    },
    "<filenameB>":{
        "title":"<check title>",
        "recommendation":"<recommendation on how to fix>"
    }
}
```

2\. Save and close the file.

3\. Restart Hacktor.

```
systemctl restart ngs-hacktor
```

## Run Custom Script

To use a custom script for a penetration test, simply add the script to the appropriate Hacktor according to the instructions. Also, be sure to allow custom scripts to run in the advanced settings of the [Audit Defintion](https://docs.enginsight.com/docs/master/operation/platform/penetration-testing/templates).

<figure><img src="https://97980696-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LTMe1v0eboWCAUTQHbT-887967055%2Fuploads%2F4booPszLQ85TFqilPHQ5%2FCustom%20Script%20ausf%C3%BChren%20eng.png?alt=media&#x26;token=70388e7f-770c-4dde-953b-d5daa4ce6d22" alt=""><figcaption></figcaption></figure>
