NSE 脚本原理
1. NSE 脚本的运行机制
NSE 的核心是一个脚本解释器,它运行用 Lua 语言编写的脚本。Nmap 会在扫描过程中加载并执行这些脚本,以扩展其核心功能。整个运行机制可以概括为以下几个步骤:
- 脚本加载:Nmap 在启动时,会根据你的命令行参数(如
-sC
或--script <脚本名>
),加载相应的 NSE 脚本。这些脚本文件通常位于 Nmap 的安装目录下的scripts
文件夹中 - 事件触发:NSE 脚本不会无缘无故地运行。它依赖于一系列的事件触发器(Triggers),这些触发器会在 Nmap 的不同扫描阶段被激活
pre-scan
:在任何主机扫描开始之前运行。通常用于一些全局性任务,如收集 DNS 信息host-scan
:在扫描每个主机时运行。通常用于对单个主机进行枚举或漏洞检测port-scan
:在扫描每个端口时运行。这是最常用的触发器,用于针对特定端口的服务进行探测,如 HTTP、FTP、SSH 等post-scan
:在所有主机扫描完成后运行。通常用于汇总结果或生成报告
- 脚本执行:当一个事件被触发时,Nmap 会调用相应脚本中的
action()
函数。这个函数包含了脚本要执行的核心逻辑 - 结果返回:
action()
函数执行完毕后,会将结果返回给 Nmap。Nmap 会将这些结果以标准的格式(如 XML、文本等)显示给用户
2. 编写 NSE 脚本的核心结构
一个典型的 NSE 脚本由以下几个关键部分组成:
- 脚本描述(
description
):一个简短的字符串,描述脚本的功能 - 分类(
categories
):脚本的分类,如safe
(安全)、vuln
(漏洞)、auth
(认证)等。这些分类使得用户可以通过-sC
或--script=safe
等参数来批量运行某一类脚本 - 依赖关系(
dependencies
):如果脚本依赖于其他脚本,可以在这里声明 - 触发器(
hostrule
、portrule
等):指定脚本在什么条件下运行。例如,portrule
规定了脚本只在发现某个特定端口开放时才运行portrule = "tcp or udp"
:在所有 TCP 或 UDP 端口上运行portrule = "port:80"
:只在 80 端口上运行hostrule
:在整个主机上运行,不依赖于特定端口
- 主函数(
action()
):这是脚本的核心代码,包含了所有业务逻辑。在这个函数中,你可以使用 Nmap 提供的各种库函数(如http.get
、nmap.set_port_state
等),来完成网络交互和数据处理