> ## Documentation Index
> Fetch the complete documentation index at: https://docs.projectdiscovery.io/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript Protocol

> Review examples of JavaScript with Nuclei v3

The JavaScript protocol was added to Nuclei v3 to allow you to write checks and detections for exploits in JavaScript and to bridge the gap between network protocols.

* Internally any content written using the JavaScript protocol is executed in Golang.
* The JavaScript protocol is **not** intended to fit into or be imported with any existing JavaScript libraries or frameworks outside of the Nuclei ecosystem.
* Nuclei provides a set of functions, libraries that are tailor-made for writing exploits and checks and only adds required/necessary functionality to complement existing YAML-based DSL.
* The JavaScript protocol is **not** intended to be used as a general purpose JavaScript runtime and does not replace matchers, extractors, or any existing functionality of Nuclei.
* Nuclei v3.0.0 ships with **15+ libraries (ssh, ftp, RDP, Kerberos, and Redis)** tailored for writing exploits and checks in JavaScript and will be continuously expanded in the future.

## Simple Example

Here is a basic example of a JavaScript protocol template:

```yaml theme={null}
id: ssh-server-fingerprint

info:
  name: Fingerprint SSH Server Software
  author: Ice3man543,tarunKoyalwar
  severity: info
  

javascript:
  - code: |
      var m = require("nuclei/ssh");
      var c = m.SSHClient();
      var response = c.ConnectSSHInfoMode(Host, Port);
      to_json(response);
    args:
      Host: "{{Host}}"
      Port: "22"

    extractors:
      - type: json
        json:
          - '.ServerID.Raw'
```

In the Nuclei template example above, we are fingerprinting SSH server software by connecting in non-auth mode and extracting the server banner.  Let's break down the template.

### Code Section

The `code:` contains actual JavaScript code that is executed by Nuclei at runtime. In the above template, we are:

* Importing `nuclei/ssh` module/library
* Creating a new instance of `SSHClient` object
* Connecting to SSH server in `Info` mode
* Converting response to json

### Args Section

The `args:` section can be simply understood as variables in JavaScript that are passed at runtime and support DSL usage.

### Output Section

The value of the last expression is returned as the output of JavaScript protocol template and can be used in matchers and extractors. If the server returns an error instead, then the `error` variable is exposed in the matcher or extractor with an error message.

## SSH Bruteforce Example

**SSH Password Bruteforce Template**

```yaml theme={null}
id: ssh-brute

info:
  name: SSH Credential Stuffing
  author: tarunKoyalwar
  severity: critical
  

javascript:
  - pre-condition: |
      var m = require("nuclei/ssh");
      var c = m.SSHClient();
      var response = c.ConnectSSHInfoMode(Host, Port);
      // only bruteforce if ssh server allows password based authentication
      response["UserAuth"].includes("password")

    code: |
      var m = require("nuclei/ssh");
      var c = m.SSHClient();
      c.Connect(Host,Port,Username,Password);

    args:
      Host: "{{Host}}"
      Port: "22"
      Username: "{{usernames}}"
      Password: "{{passwords}}"

    threads: 10
    attack: clusterbomb
    payloads:
      usernames: helpers/wordlists/wp-users.txt
      passwords: helpers/wordlists/wp-passwords.txt

    stop-at-first-match: true
    matchers:
      - type: dsl
        dsl:
          - "response == true"
          - "success == true"
        condition: and
```

In the example template above, we are bruteforcing ssh server with a list of usernames and passwords. We can tell that this might not have been possible to achieve with the network template. Let's break down the template.

### Pre-Condition

`pre-condition` is an optional section of JavaScript code that is executed before running “code” and acts as a pre-condition to exploit. In the above template, before attempting brute force, we check if:

* The address is actually an SSH server.
* The ssh server is configured to allow password-based authentication.

**Further explanation**

* If pre-condition returns `true` only then `code` is executed; otherwise, it is skipped.
* In the code section, we import `nuclei/ssh` module and create a new instance of `SSHClient` object.
* Then we attempt to connect to the ssh server with a username and password.
  This template uses [payloads](https://docs.projectdiscovery.io/templates/protocols/http/http-payloads) to launch a clusterbomb attack with 10 threads and exits on the first match.

Looking at this template now, we can tell that JavaScript templates are powerful for writing multistep and protocol/vendor-specific exploits, which is a primary goal of the JavaScript protocol.

## Init

`init` is an optional JavaScript section that can be used to initialize the template, and it is executed just after compiling the template and before running it on any target. Although it is rarely needed, it can be used to load and preprocess data before running a template on any target.

For example, in the below code block, we are loading all ssh private keys from `nuclei-templates/helpers` directory and storing them as a variable in payloads with the name `keys`. If we were loading private keys from the "pre-condition" code block, then it would have been loaded for every target, which is not ideal.

```
variables:
  keysDir: "helpers/"  # load all private keys from this directory

javascript:
    # init field can be used to make any preperations before the actual exploit
    # here we are reading all private keys from helpers folder and storing them in a list
  - init: |
      let m = require('nuclei/fs');
      let privatekeys = m.ReadFilesFromDir(keysDir)
      updatePayload('keys',privatekeys)

    payloads:
      # 'keys' will be updated by actual private keys after init is executed
      keys: 
        - key1
        - key2
```

Two special functions that are available in the `init` block are

| Function                   | Description                              |
| -------------------------- | ---------------------------------------- |
| `updatePayload(key,value)` | updates payload with given key and value |
| `set(key,value)`           | sets a variable with given key and value |

A collection of JavaScript protocol templates can be found [here](https://github.com/projectdiscovery/nuclei-templates/pull/8530).
