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.
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
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
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
Ldap / kerberos exploits usually involves multi step process of authentication and then exploitation etc and not easy to write in YAML based DSL
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
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 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)
API reference of all exposed modules and functions can be found here.
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
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 contains actual javascript code that is executed by nuclei engine at runtime In above template we are
nuclei/ssh
module/librarySSHClient
objectInfo
modeArgs can be simply understood as variables in javascript that are passed at runtime and support DSL usage
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.
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
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
Furthur explaination
true
only then code is executed otherwise it is skippednuclei/ssh
module and create a new instance of SSHClient
objectLooking 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
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.
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.