Profile Image

Mantas Sabeckis

Security Researcher

Building Own Nuclei Templates

It’s time to break the atoms! We will take a look at how it’s possible to create unique nuclei templates! Don’t miss out, since I will show you 3 easy ways how you can build your own! Let’s increase your chance of raking that bounty cash! I have another article about the smart ways to use this tool itself, if you haven’t read that, feel free to check it out!

Nuclei templates are made for testing certain vulnerabilities. Either it’s known misconfigurations, CVEs, default credentials, general fuzzing techniques, and even more! It’s a pretty powerful way to describe how you can detect the issues, and it’s also a very powerful technique to test at a mass scale. This tool comes with a lot of templates already premade, but using them out of the box, will most likely result in duplicate findings. Using your custom templates will increase the chance of finding vulnerabilities by a lot! What if I told you that you don’t need to put a lot of effort into making your own? There is no need to read a lot of documentation when you are starting out. It’s pretty simple, once you understand the basics.

Watch this video in case you are too lazy to read 😊

Default Directory Structure

To make building your own templates easier, it’s just mandatory to understand the base structure. When you install nuclei, templates by default will be in your home directory. If I list them out, you will see there are multiple categories and multiple directories:

Those directories separate templates by their use case, and the way how you run them:

  • headless – meant for the templates for headless mode.
  • dns – for checking DNS records mostly.
  • file – will have various checks specified files. Because you can also pass not URLs, but files to the tool.
  • http – just regular HTTP requests. We will spend our focus here this time since it’s just the most common way of using Nuclei.
  • javascript – in case you want to run some JavaScript functions on the client side.
  • network – if you have, for instance, IPs with different ports, you can do some network-based scanning.
  • ssl – for SSL checks.

Others like code, config, helpers, and workflows are basically a bit advanced stuff!

Structure of Templates

Templates are written in YAML, it’s a pretty simple way to describe data, mostly using key-value pairs. If we check dns -> azure-takeover-detection.yaml template, we will see the 3 main parts:

  • The 1st part is meant for id, which is basically the unique identifier of the template:

It’s meant for in case you only want to use that template only. You can use it with nuclei using this command:

nuclei -u target.com -id azure-takeover-detection 
  • The second part is the info part:

It will have some metadata. Some of those values are mandatory, like the name of the template, the author who made the template, the severity (usually by CVSS score), and the description but other parts are optional like reference, classification, and metadata.

The last part usually will be tags. The tags are also mandatory since this one could be used when you want to run multiple templates of certain group. For this example, the dns tag could be used to run the DNS templates in this directory. To run templates of specific group, you could use the following command:

nuclei -u target.com -tags dns
  • The 3rd part is the most important, and this one tells the nuclei tool how you want to use templates:

Here, the dns will tell the nuclei how you want to send the DNS request, and the matchers will specify the condition when to display output to the terminal. In this case, if the DNS record contains string 69.164.223.206.

There are other types of part 3 structure, for example – file, which could be used for scanning files using nuclei like in python-scanner.yaml template:

As you notice first 2 parts are the same – id and info, but the third part will be the file.

Even though nuclei has many options for templates, most people use it mainly for sending HTTP requests, so let’s explore HTTP-based templates. There are multiple main ways to write HTTP-based templates. Let’s explore the phpmyadmin-misconfiguration.yaml file:

It’s a phpmyadmin misconfiguration template with an id and info parts which we already know, but this time you can see there is an http section. There are multiple ways to send HTTP requests using nuclei:

  • You can use the GET method and specify the paths you want to fetch and after getting those paths, detect them. In this case, it is sending 2 requests to /phpmyadmin endpoints and checking if responses contain strings of “var db = ‘information_schema’;” and “var opendb_url = ‘db_structure.php’;” followed by a status code of 200.
  • There is also a possibility of doing it for HTTP requests similar to Burp Suite. For instance, we can check a GET request on a phpmyadmin-unauth.yaml file:

As you can notice, you can use the raw keyword and specify the request as you see in Burp. This way you can also send HTTP requests using other verbs like POST, PUT, etc.

Method #1

As we just learned the core structure of templates, now it’s time for the first method on how you can build your own. I recommend starting by just reading already premade ones and trying to do something similar. What I like to do, is split my terminal in two parts, and on the left side, I will have already made a nuclei template, and on the right side, the template that I will be building. For this case, I have selected aem-xss-childrenlist-xss.yaml file as an example:

On the right side, I have opened a new file using the nano editor called the same name as the template on the right. I have created it on ~/nuclei-templates-cust/ directory.

The first step using this approach is just to try to copy everything from the left side to the right and then edit it:

As you probably noticed, using editors like nano, has some drawbacks – while copying, some lines could be truncated. In this case, it’s just description. It won’t matter that much but in other cases, you could make some easy mistakes, so keep this in mind. I would suggest using better text editors like vscode. I like to stay in terminals all the time, so I will use nano for this run.

So back into editing a custom template… I want to use a prompt() function instead of alert(). The idea is to use a modified template in case WAF blocks alert() JS functions. To do this, the path and matcher have to be replaced:

I have also added myself as the author while giving credit to the original author as well. Hit ctrl+s and your fresh template will be ready to go! This is the simplest way to start exploring nuclei templating engine and it’s just a matter of imagination what you can do. You could try adding more endpoints near {{BaseURL}}, you could try modifying the payloads, etc.

Another good example of using this method is trying to find the LFI. Usually, LFI templates are looking for /etc/passwd files, but you could modify them to search for Windows OS files! Just replace the payloads and the matchers and you will be ready to go.

Sometimes you can play around with changing methods, instead of GET you can try to change to POST or PUT and you will be pretty surprised by what you can find. Just don’t use it on known CVEs.

Method #2

After playing around with existing templates and maybe reading the documentation of templates, you will be down the rabbit hole of nuclei templating. The second thing to level up your game is checking security feeds and oh boy it’s a pretty darn good way to get some inspiration for building your own template from scratch. My two favorite places to go to get some ideas are the X and HackerOne hacktivity.

So in X, you should use those search fields – #bugbountytips and vulnerability type.

Ideally, you wanna find payloads and vulnerable endpoints. It’s also a good idea to add the payloads keyword:

On HackerOne you should also want to find disclosed reports for your desired vulnerability type:

Next, you want to find a similar existing nuclei template and try to copy that template again to the new one and like previously just replace payloads or endpoints.

Method #3

Lastly, the final method is doing security research. There is a simple way of doing it and there is a hard way:

The easy way is to find to search recent CVEs and try to find the exploit code before everybody else and create the nuclei template around it. The usual place to go to search for exploits is usually GitHub. What I like to do is write down CVE and the current year of the CVE and sort by recently updated:

This way you can find a lot of exploits by date. Usually, those are written in Python so you also need to sort by Python language at the side menu.

Also, a good idea is to check if that CVE number is not yet already included in the default nuclei templates repository. If it’s already included in the nuclei templates, you won’t have a lot of chance of finding the CVE on your targets first. So basically it’s like a rat race at this point…

In case you want to have a 99% of chance not getting duplicates, you should be professional, and do it professionally – by doing security research, which is a hard way. You will need to read the code of targeted software that many bug bounty programs use, understand where and how vulnerabilities occur, and try to find zero days. To find zero days I recommend picking open open-source project on either GitHub, Dockerhub, or any other place and trying to reverse engineer it, read the code, and try to find vulnerabilities. For those vulnerabilities, you should create the nuclei template. Whitebox security testing is a huge topic and this article is already getting chunky so I won’t get into much of details this time.

Last Thoughts

If you stayed up to this point, congratulations because you have enough knowledge to get the ball rolling on your nuclei template construction work!

If you find this information useful, please share this article on your social media, I will greatly appreciate it! I am active on Twitter, check out some content I post there daily! If you are interested in video content, check my YouTube. Also, if you want to reach me personally, you can visit my Discord server. Cheers!

Share with your friends