Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javascript protocol for scripting (includes 15+ proto libs) #4109

Merged
merged 54 commits into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d199c36
rebase js-layer PR from @ice3man543
tarunKoyalwar Sep 1, 2023
3dfd296
package restructuring
tarunKoyalwar Sep 1, 2023
d27a72e
working
tarunKoyalwar Sep 1, 2023
f858678
fix duplicated event & matcher status
tarunKoyalwar Sep 1, 2023
4b9aa07
fix lint error
tarunKoyalwar Sep 1, 2023
35faf56
fix response field
tarunKoyalwar Sep 1, 2023
105c2c8
add new functions
tarunKoyalwar Sep 3, 2023
ee770e1
multiple minor improvements
tarunKoyalwar Sep 4, 2023
c5a84f0
fix incorrect stats in js protocol
tarunKoyalwar Sep 5, 2023
27012c9
sort output metadata in cli
tarunKoyalwar Sep 5, 2023
9865cdf
remove temp files
tarunKoyalwar Sep 5, 2023
2815639
remove dead code
tarunKoyalwar Sep 5, 2023
c1d6654
add unit and integration test
tarunKoyalwar Sep 5, 2023
eb5a475
fix lint error
tarunKoyalwar Sep 5, 2023
3302bd6
add jsdoclint using llm
tarunKoyalwar Sep 5, 2023
e7fd60b
Merge branch 'v3-beta' into feat-js-protocol
tarunKoyalwar Sep 5, 2023
7d2fc22
fix error in test
tarunKoyalwar Sep 5, 2023
3bc8bbd
add js lint using llm
tarunKoyalwar Sep 5, 2023
a72a3d6
generate docs of libs
tarunKoyalwar Sep 5, 2023
f8944f2
llm lint
tarunKoyalwar Sep 5, 2023
2165c2c
remove duplicated docs
tarunKoyalwar Sep 5, 2023
0965f2e
update generated docs
tarunKoyalwar Sep 5, 2023
b11cb1c
update prompt in doclint
tarunKoyalwar Sep 5, 2023
66c9e4c
update docs
tarunKoyalwar Sep 5, 2023
0635eb8
temp disable version check test
tarunKoyalwar Sep 5, 2023
ebc3092
fix unit test and add retry
tarunKoyalwar Sep 5, 2023
1dfb106
fix panic in it
tarunKoyalwar Sep 6, 2023
e0b5d3f
update and move jsdocs
tarunKoyalwar Sep 6, 2023
caa3dcd
updated jsdocs
tarunKoyalwar Sep 6, 2023
e06312b
update docs
tarunKoyalwar Sep 11, 2023
d6831d7
update container platform in test
tarunKoyalwar Sep 11, 2023
5f7ddb6
dir restructure and adding docs
tarunKoyalwar Sep 11, 2023
e41fb81
add api_reference and remove markdown docs
tarunKoyalwar Sep 11, 2023
cd3f481
fix imports
tarunKoyalwar Sep 11, 2023
7085b47
add javascript design and contribution docs
tarunKoyalwar Sep 11, 2023
e1e7d21
add js protocol documentation
tarunKoyalwar Sep 11, 2023
39cbfb2
update integration test and docs
tarunKoyalwar Sep 11, 2023
7d896fa
update doc ext mdx->md
tarunKoyalwar Sep 11, 2023
8b8cee0
minor update to docs
tarunKoyalwar Sep 11, 2023
90f6819
new integration test and more
tarunKoyalwar Sep 12, 2023
ce5435c
move go libs and add docs
tarunKoyalwar Sep 12, 2023
538a744
gen new net docs and more
tarunKoyalwar Sep 12, 2023
d58343c
final docs update
tarunKoyalwar Sep 12, 2023
b1f00ac
add new devtool
tarunKoyalwar Sep 12, 2023
1ee7a30
use fastdialer
tarunKoyalwar Sep 13, 2023
b9d0b4b
resolve merge conflicts
tarunKoyalwar Sep 13, 2023
b428c6f
fix build fail
tarunKoyalwar Sep 13, 2023
aff7da2
use fastdialer + network sandbox support
tarunKoyalwar Sep 13, 2023
07607ee
add reserved keyword 'Port'
tarunKoyalwar Sep 13, 2023
f4155e3
update Port to new syntax
tarunKoyalwar Sep 13, 2023
e3125e5
misc update
ehsandeep Sep 14, 2023
9f00f6e
always enable templatectx in js protocol
tarunKoyalwar Sep 15, 2023
3619ad5
move docs to 'js-proto-docs' repo
tarunKoyalwar Sep 15, 2023
c9d753d
remove scrapefuncs binary
tarunKoyalwar Sep 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,11 @@ v2/pkg/protocols/common/helpers/deserialization/testdata/ValueObject.class
v2/pkg/protocols/common/helpers/deserialization/testdata/ValueObject2.ser
*.exe
v2/.gitignore
v2/pkg/js/devtools/bindgen/cmd/bindgen
v2/pkg/js/devtools/jsdocgen/jsdocgen
bindgen
jsdocgen
nuclei
v2/scrapefuncs
*.DS_Store
v2/pkg/protocols/headless/engine/.cache
1 change: 1 addition & 0 deletions docs/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"template-guide/network",
"template-guide/dns",
"template-guide/file",
"template-guide/javascript",
{
"group": "Operators",
"pages": [
Expand Down
185 changes: 185 additions & 0 deletions docs/template-guide/javascript.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
title: "Javascript"
---

## Introduction

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](https://github.com/dop251/goja)**.


## Features

- **Provider/Driver specific exploit**

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

- **Non Network Checks**

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

1. local privilege escalation checks
2. kernel exploits
3. account misconfigurations
4. system misconfigurations etc

- **Complex network protocol exploits**

Some network exploits are very complex to write due to nature of protocol or exploit itself example [CVE-2020-0796](https://nvd.nist.gov/vuln/detail/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

- **Multi Step Exploits**

Ldap / kerberos exploits usually involves multi step process of authentication and then exploitation etc and not easy to write in YAML based DSL

- **Scalable and maintainable exploits**

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

- **Leveraging turing complete language**

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

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)

## Requirements

- A bare minimum knowledge of javascript (loops, functions , arrays is enough) is required to write javascript protocol template
- Nuclei v3.0.0 or above


## API Reference

API reference of all exposed modules and functions can be found [here](https://projectdiscovery.github.io/js-proto-docs/).

## Javascript Protocol

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

- It is not intended to fit / imported with any existing javascript libraries or frameworks outside of nuclei ecosystem.
- Nuclei Engine provides a set of functions, libraries that are tailor made for writing exploits / checks and only adds required/necessary functionality to compliment existing YAML based DSL.
- It is not intended to be used as general purpose javascript runtime and does not replace matchers or extractors or any existing functionality of nuclei.
- Javascript Protocol is intended to bridge gap between network protocol to add any new xyz protocol while adding lot of other functionalities.
- Nuclei v3.0.0 ships with **15+ libraries (ssh,ftp,rdp,kerberos,redis)** tailored for writing exploits/checks in javascript and will be continiously expanded in future.

Here is a simple example of javascript protocol template

```yaml
id: ssh-server-fingerprint

info:
name: Fingerprint SSH Server Software
author: Ice3man543,tarunKoyalwar
severity: info


javascript:
- code: |
var m = require("nuclei/ssh");
var c = m.SSHClient();
var response = c.ConnectSSHInfoMode(Host, Port);
to_json(response);
args:
Host: "{{Host}}"
Port: "22"

extractors:
- type: json
json:
- '.ServerID.Raw'
```

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

Code contains actual javascript code that is executed by nuclei engine at runtime In above template we are

- importing `nuclei/ssh` module/library
- creating a new instance of `SSHClient` object
- connecting to SSH server in `Info` mode
- converting response to json

### Args

Args can be simply understood as variables in javascript that are passed at runtime and support DSL usage


### **Output**

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.

### Example

**SSH Password Bruteforce Template**

```yaml
id: ssh-brute

info:
name: SSH Credential Stuffing
author: tarunKoyalwar
severity: critical


javascript:
- pre-condition: |
var m = require("nuclei/ssh");
var c = m.SSHClient();
var response = c.ConnectSSHInfoMode(Host, Port);
// only bruteforce if ssh server allows password based authentication
response["UserAuth"].includes("password")

code: |
var m = require("nuclei/ssh");
var c = m.SSHClient();
c.Connect(Host,Port,Username,Password);

args:
Host: "{{Host}}"
Port: "22"
Username: "{{usernames}}"
Password: "{{passwords}}"

threads: 10
attack: clusterbomb
payloads:
usernames: helpers/wordlists/wp-users.txt
passwords: helpers/wordlists/wp-passwords.txt

stop-at-first-match: true
matchers:
- type: dsl
dsl:
- "response == true"
- "success == true"
condition: and
```

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

`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
- address is actually a ssh server
- ssh server is configured to allow password based authentication

**Furthur explaination**

- If pre-condition returns `true` only then code is executed otherwise it is skipped
- In code section we import `nuclei/ssh` module and create a new instance of `SSHClient` object
- and then we attempt to connect to ssh server with username and password
- this template uses [payloads](https://docs.nuclei.sh/template-guide/http/http-payloads) to launch a clusterbomb attack with 10 threads and exits on first match

Looking 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.

A collection of javascript protocol templates can be found [here](https://github.com/projectdiscovery/nuclei-templates/pull/8206).

## Contributing

If you want to add a new module or function to nuclei javascript runtime please open a PR with your changes, refer [Contributing](https://github.com/projectdiscovery/nuclei/blob/7085b47c19dbe3a70b3d4eb23177995bda5c285a/v2/pkg/js/CONTRIBUTE.md) for more details.
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-env-var.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ code:
- type: word
words:
- "hello from input baz"
# digest: 4a0a00473045022100e17c7a809fd64419baf401b5331edab3a68a4c182f7777614beb1862eb6ea8b7022011b95fc0e22d7f82e08e01b56ce87afdbe03027c238ba290a058d695226173ae
# digest: 4a0a004730450221009b73a0d173beca99aff61fcfe366d929760411f0b9facfe5502a0f2e677342fa02201327b024e52a89891bb90ecdd2f7521370fe40ac89b3f93e9e5f5072f0192de7
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ code:
- type: word
words:
- "hello from input"
# digest: 490a004630440220241d7faae14ab5760dbe7acf621a3923d0650148bc14a52a9be06ba76e8e0abf02201885fcc432d354d3c99ea97b964838719451bc97f148229f187f61eee7525eb6
# digest: 490a00463044022037b485132a0ff1f52bde1ce71908fd692d93d9cda15d5b70275c7fc89a0aa257022043f36ca1c7062d4d74dde377e5a0065c1507bfcad2a8389772eebfa99fd16af2
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-interactsh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ code:
part: interactsh_protocol
words:
- "http"
# digest: 490a004630440220427cb7100f0b7d95224f490a6f4f626186782cb26c69f2551d6aefcdbc7c17d20220206161ad3a98afe8fcef9dd06d9a6dd5f34c5f7e3cd3ab7f81328f033dcd2b48
# digest: 4a0a004730450221008d0e317bd37ab7dfdbaf3d26ed2072521f0ea00a61d45d0e6d592886faeac1840220410070cd29ffa05113b387c5afcd13fd65dab2b67f21583a1aeddb352ab5aa88
2 changes: 1 addition & 1 deletion integration_tests/protocols/code/py-snippet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ code:
- type: word
words:
- "hello from input"
# digest: 4a0a00473045022056092462597e85139626656d37df123094cb3861bdf583450c38814bac8df9cb022100e83a8c552f8f8a098f6b7ec8a32c6b448b995e000884beadb50cb0f2720117de
# digest: 4b0a00483046022100b7fef4d710fa7e3b8916dc990a381551deb42c558d92a043358325f3994078f5022100db47c9f752185ad42af1a5268788567f88fcd8e41053674fdb637f01f02bbbaa
32 changes: 32 additions & 0 deletions integration_tests/protocols/javascript/net-multi-step.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
id: network-multi-step
info:
name: network multi-step
author: tarunKoyalwar
severity: high
description: |
Network multi-step template for testing


javascript:
- code: |
var m = require("nuclei/net");
var conn = m.Open("tcp",address);
conn.SetTimeout(timeout); // optional timeout
conn.Send("FIRST")
conn.RecvString(4) // READ 4 bytes i.e PING
conn.Send("SECOND")
conn.RecvString(4) // READ 4 bytes i.e PONG
conn.RecvString(6) // READ 6 bytes i.e NUCLEI

args:
address: "{{Host}}:{{Port}}"
Host: "{{Host}}"
Port: 5431
timeout: 3 # in sec

matchers:
- type: dsl
dsl:
- success == true
- response == "NUCLEI"
condition: and
43 changes: 43 additions & 0 deletions integration_tests/protocols/javascript/redis-pass-brute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
id: redis-pass-brute
info:
name: redis password bruteforce
author: tarunKoyalwar
severity: high
description: |
This template bruteforces passwords for protected redis instances.
If redis is not protected with password. it is also matched
metadata:
shodan-query: product:"redis"


javascript:
- pre-condition: |
isPortOpen(Host,Port)

code: |
var m = require("nuclei/redis");
m.GetServerInfoAuth(Host,Port,Password);

args:
Host: "{{Host}}"
Port: "6379"
Password: "{{passwords}}"

payloads:
passwords:
- ""
- root
- password
- admin
- iamadmin
stop-at-first-match: true

matchers-condition: and
matchers:
- type: word
words:
- "redis_version"
- type: word
negative: true
words:
- "redis_mode:sentinel"
26 changes: 26 additions & 0 deletions integration_tests/protocols/javascript/ssh-server-fingerprint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
id: ssh-server-fingerprint

info:
name: Fingerprint SSH Server Software
author: Ice3man543,tarunKoyalwar
severity: info
metadata:
shodan-query: port:22


javascript:
- code: |
var m = require("nuclei/ssh");
var c = m.SSHClient();
var response = c.ConnectSSHInfoMode(Host, Port);
to_json(response);
args:
Host: "{{Host}}"
Port: "22"

extractors:
- type: json
name: server
json:
- '.ServerID.Raw'
part: response
5 changes: 5 additions & 0 deletions v2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ functional:
cd cmd/functional-test; bash run.sh
tidy:
$(GOMOD) tidy
devtools:
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "bindgen" pkg/js/devtools/bindgen/cmd/bindgen/main.go
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "jsdocgen" pkg/js/devtools/jsdocgen/main.go
$(GOBUILD) $(GOFLAGS) -ldflags '$(LDFLAGS)' -o "scrapefuncs" pkg/js/devtools/scrapefuncs/main.go

1 change: 1 addition & 0 deletions v2/cmd/integration-test/integration-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var (
"generic": genericTestcases,
"dsl": dslTestcases,
"flow": flowTestcases,
"javascript": jsTestcases,
}

// For debug purposes
Expand Down
Loading
Loading