Documentation Index
Fetch the complete documentation index at: https://projectdiscovery.sec-lab.cn/llms.txt
Use this file to discover all available pages before exploring further.
JavaScript 协议被添加到 Nuclei v3 中,允许你用 JavaScript 编写检查和检测漏洞,并弥合网络协议之间的差距。
- 内部使用 JavaScript 协议编写的任何内容都在 Golang 中执行。
- JavaScript 协议不旨在适配或导入 Nuclei 生态系统之外的任何现有 JavaScript 库或框架。
- Nuclei 提供了一套专为编写漏洞利用和检查而量身定制的函数、库,只添加必要的功能来补充现有的基于 YAML 的 DSL。
- JavaScript 协议不旨在用作通用 JavaScript 运行时,也不会替代 Nuclei 的 matchers、extractors 或任何现有功能。
- Nuclei v3.0.0 附带了15+ 库(ssh、ftp、RDP、Kerberos 和 Redis),专为在 JavaScript 中编写漏洞利用和检查而定制,未来将不断扩展。
简单示例
以下是 JavaScript 协议模板的基本示例:
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'
在上面的 Nuclei 模板示例中,我们通过以非认证模式连接并提取服务器横幅来识别 SSH 服务器软件。让我们分解一下这个模板。
代码部分
code: 包含在运行时由 Nuclei 执行的实际 JavaScript 代码。在上面的模板中,我们:
- 导入
nuclei/ssh 模块/库
- 创建
SSHClient 对象的新实例
- 以
Info 模式连接到 SSH 服务器
- 将响应转换为 json
参数部分
args: 部分可以简单理解为在运行时传递的 JavaScript 变量,支持 DSL 使用。
输出部分
最后一个表达式的值作为 JavaScript 协议模板的输出返回,可以在 matchers 和 extractors 中使用。如果服务器返回错误,则在 matcher 或 extractor 中会暴露带有错误消息的 error 变量。
SSH 暴力破解示例
SSH 密码暴力破解模板
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);
// 只有当 ssh 服务器允许基于密码的认证时才进行暴力破解
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
在上面的示例模板中,我们使用用户名和密码列表对 ssh 服务器进行暴力破解。我们可以看出,这可能无法通过网络模板实现。让我们分解一下这个模板。
前置条件
pre-condition 是在运行 “code” 之前执行的可选 JavaScript 代码部分,它作为漏洞利用的前提条件。在上面的模板中,在尝试暴力破解之前,我们检查:
- 该地址确实是 SSH 服务器。
- ssh 服务器配置为允许基于密码的认证。
进一步解释
- 如果 pre-condition 返回
true,则只执行 code;否则,跳过。
- 在代码部分,我们导入
nuclei/ssh 模块并创建 SSHClient 对象的新实例。
- 然后我们尝试使用用户名和密码连接到 ssh 服务器。
该模板使用 payloads 启动具有 10 个线程的 clusterbomb 攻击,并在首次匹配时退出。
现在看这个模板,我们可以看出 JavaScript 模板在编写多步骤和协议/供应商特定的漏洞利用方面非常强大,这是 JavaScript 协议的主要目标。
初始化
init 是一个可选的 JavaScript 部分,可用于初始化模板,它在编译模板后、在任何目标上运行之前执行。虽然很少需要,但它可以用于在针对任何目标运行模板之前加载和预处理数据。
例如,在下面的代码块中,我们从 nuclei-templates/helpers 目录加载所有 ssh 私钥,并将它们作为名为 keys 的变量存储在 payloads 中。如果我们从 “pre-condition” 代码块加载私钥,那么它将为每个目标加载,这不是理想的。
variables:
keysDir: "helpers/" # 从此目录加载所有私钥
javascript:
# init 字段可用于在实际漏洞利用之前进行任何准备工作
# 这里我们从 helpers 文件夹读取所有私钥并将它们存储在列表中
- init: |
let m = require('nuclei/fs');
let privatekeys = m.ReadFilesFromDir(keysDir)
updatePayload('keys',privatekeys)
payloads:
# 'keys' 将在 init 执行后由实际私钥更新
keys:
- key1
- key2
init 块中有两个特殊功能
| 函数 | 描述 |
|---|
updatePayload(key,value) | 使用给定的键和值更新 payload |
set(key,value) | 使用给定的键和值设置变量 |
可以在这里找到 JavaScript 协议模板的集合。