Javascript
Introduction
Nuclei and its community thrives on its ability to write exploits/checks in fast and simple way in YAML format and we aim to make nuclei templates as standard for writing security checks and that comes with understanding its limitations and addressing them as well as expanding its capabilities. It is already possible to write most complex HTTP, DNS, SSL protocol exploits / checks with increasing support and a powerful and easy to use DSL in nuclei engine but we understand this may not be enough for addressing / writing vulnerabilities across all protocols as well as other non-remote domains of security like local privilege escalation checks, kernel etc.
To address this and expand to other domains of security, Nuclei v3 ships with a embedded runtime for javascript that is tailored for Nuclei with the help of Goja.
Features
- Provider/Driver specific exploit
Some vulnerabilities are specific to software/driver, example a redis buffer overflow exploit or a exploit of specific VPN software or anything that’s not a IETF standard protocol. since they are not standard protocols and it doesn’t make much sense to add them as a protocol in nuclei. Such exploits cannot be written using ‘network’ protocol or Very complex to write, such exploits can be written by exposing required library in nuclei (if not already present) and writing actual exploit in javascript protocol minus the boilerplate and scaling issues and other goodies of nuclei
- Non Network Checks
Security is not limited to network and nuclei also doesn’t intend to limit itself to network only. There are lot of security checks that are not network related like
- local privilege escalation checks
- kernel exploits
- account misconfigurations
- system misconfigurations etc
- Complex network protocol exploits
Some network exploits are very complex to write due to nature of protocol or exploit itself example CVE-2020-0796 where you have to manually construct a packet. such exploits are usually written in python but now can be written in javascript protocol itself
- Multi Step Exploits
Ldap / kerberos exploits usually involves multi step process of authentication and then exploitation etc and not easy to write in YAML based DSL
- Scalable and maintainable exploits
One off exploits written in code are not scalable and maintainable due to nature of language , boilerplate code and lot of other factors. The goal here is to only write bare minimum code required to run exploit and let nuclei engine handle the rest
- Leveraging turing complete language
While YAML based DSL is powerful and easy to use it is not turing complete and has its own limitations. Javascript is turing complete thus users who are already familiar with javascript can write network and other exploits without learning new DSL or hacking around existing DSL.
Goja
Goja is ECMAScript/Javascript engine/runtime written in pure go and has full support for ECMAScript 5.1. It is fast, can be used in goroutines and has very small memory footprint which makes it good fit for embedding in nuclei and provides additional layer of security and flexibility due to nature of javascript language and its implementation.
This does not break any nuclei design principle nor does it change how nuclei works and is dependency free. It complements nuclei engine by adding existing turing complete language (i.e javascript) instead of re-inventing the wheel by creating new DSL (domain specific language)
Requirements
- A bare minimum knowledge of javascript (loops, functions , arrays is enough) is required to write javascript protocol template
- Nuclei v3.0.0 or above
API Reference
API reference of all exposed modules and functions can be found here.
Javascript Protocol
Javascript protocol is new protocol added in nuclei v3 to allow writing exploits / checks in javascript language but internally are executed in go. And this javscript is tailored towards nuclei ecosystem this means
- It is not intended to fit / imported with any existing javascript libraries or frameworks outside of nuclei ecosystem.
- Nuclei Engine provides a set of functions, libraries that are tailor made for writing exploits / checks and only adds required/necessary functionality to compliment existing YAML based DSL.
- It is not intended to be used as general purpose javascript runtime and does not replace matchers or extractors or any existing functionality of nuclei.
- Javascript Protocol is intended to bridge gap between network protocol to add any new xyz protocol while adding lot of other functionalities.
- Nuclei v3.0.0 ships with 15+ libraries (ssh,ftp,rdp,kerberos,redis) tailored for writing exploits/checks in javascript and will be continiously expanded in future.
Here is a simple example of javascript protocol template
In above nuclei template we are fingerprinting SSH Server Software by connecting in Non-Auth mode and extracting server banner. Lets break down the template.
Code
Code contains actual javascript code that is executed by nuclei engine at runtime In 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
Args can be simply understood as variables in javascript that are passed at runtime and support DSL usage
Output
Value of Last expression is returned as output of javascript protocol template and can be used in matchers / extractors. If server returns an error instead then error
variable is exposed in matcher/extractor with error message.
Example
SSH Password Bruteforce Template
In above nuclei template we are bruteforcing ssh server with list of usernames and passwords. We can tell that this might not have been possible to achieve with network template Let’s break down the template.
Pre-Condition
pre-condition
is a optional javascript code that is executed before running “code” and acts as pre-condition to exploit. In above template before attempting to bruteforce we are checking if
- address is actually a ssh server
- ssh server is configured to allow password based authentication
Furthur explaination
- If pre-condition returns
true
only then code is executed otherwise it is skipped - In code section we import
nuclei/ssh
module and create a new instance ofSSHClient
object - and then we attempt to connect to ssh server with username and password
- this template uses payloads to launch a clusterbomb attack with 10 threads and exits on first match
Looking at this template now we can tell that javascript template is very powerful to write multi step and protocol/vendor specific exploits which is primary goal of javascript protocol.
Init
init
is a optional javascript code that can be used to initialize template and it is executed just after compiling template and before running it on any target. Although rarely needed, it can be used to load and preprocess data before running template on any target.
For example in below code block we are loading all ssh private keys from nuclei-templates/helpers
directory and storing them as a variable in payloads with name keys
, if we were loading private keys from ‘pre-condition’ code block then it would have been loaded for every target which is not ideal.
Two special functions that are available in 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.
Contributing
If you want to add a new module or function to nuclei javascript runtime please open a PR with your changes, refer Contributing for more details.