Nmap脚本引擎原理
Nmap脚本引擎原理
一、NSE介绍
虽然Nmap内嵌的服务于版本探测已足够强大,但是在某些情况下我们需要多伦次的交互才能够探测到服务器的信息,这时候就需要自己编写NSE插件实现这个功能。NSE插件能够完成网络发现、复杂版本探测、脆弱性探测、简单漏洞利用等功能。
转载请注明出处:http://www.cnblogs.com/liun1994/
在文章 "Nmap脚本文件分析(AMQP协议为例)" 中会将版本探测,NSE脚本原理联系起来,具体分析Nmap探测的执行过程。
在文章 " 编写自己的NSE脚本" 中将以一个简单的例子说明NSE的编写。
脚本扫描通过选项被激活
-sC: 使通用scripts生效
--script: 指定自己的脚本文件
--script-trace: 查看脚本执行过程
-A: 同时进行版本探测和脚本扫描 为了不进行主机发现也不进行端口扫描,直接使用自定义的脚本探测。可以使用下面的选项:
-Pn -sn --script --script-args和--script-args-file,指定脚本要读入的参数
nmap --script snmp-sysdescr --script-args snmpcommunity=admin example.com nmap --script default,safe 加载default和safe类脚本。
参考: https://nmap.org/book/nse-usage.html#nse-categories
脚本文件分类:brute、default、dos、safe、exploit等,具体的可查看:https://nmap.org/book/nse-usage.html#nse-categories
根据脚本的运行阶段不同分为四类:Prerule scripts、Host scripts、Service scripts、Postrule scripts。
应用最多的就是Service scripts,Post scripts对Nmap输出进行格式化输出,Host scripts这个阶段在Nmap运行完主机发现、端口扫描、版本探测、OS侦测后执行;Prerule scripts执行一些资源操作,先于各探测执行。
二、Nmap执行原理图

由上图可以看到四类脚本的运行阶段,以及他们的功能。
1)在nmap_main里面,调用init_main()进行详细的初始化过程,加载Lua标准库与Nmap扩展库,准备参数环境,加载并执行nse_main.lua文件;这个文件加载用户选择的脚本文件,执行完之后返回函数对象给init_main(),被保存到Lua注册表中。
2)在nse_main.lua中,定义两个核心的类,Script和Thread,Script用于管理NSE脚本,当新的脚本被加载时,调用 Script.new创建脚本对象,该对象被保存下来在后续的扫描过程中使用;Thread用于管理脚本的执行,该类中也包含对脚本健全性的检查。在脚本执行时,如果脚本之间存在依赖关系,那么会将基础的无依赖的脚本统一执行完毕,再执行依赖性的脚本。
3)执行脚本扫描时,从nmap_main()中调用script_scan()函数。在进入script_scan()后,会标记扫描阶段类型,然后进入到初始化阶段返回的main()函数(来自nse_main.lua脚本中的main)中,在函数中解析具体的扫描类型。
4)main()函数负责处理三种类型的脚本扫描:预扫描(SCRIPT_PRE_SCAN)、脚本扫描(SCRIPT_SCAN)、后扫描 (SCRIPT_POST_SCAN)。预扫描即在Nmap调用的最前面(没有进行主机发现、端口扫描等操作)执行的脚本扫描,通常该类扫描用于准备基本的信息,例如到第三服务器查询相关的DNS信息。而脚本扫描,是使用NSE脚本来扫描目标主机,这是最核心的扫描方式。后扫描,是整个扫描结束后,做一些善后处理的脚本,比如优化整理某些扫描。
5)在main()函数中核心操作由run函数负责。而run()函数的本身设计用于执行所有同一级别的脚本(根据依赖关系划分的级别),直到所有线程执行完毕才退出。run()函数中实现三个队列:执行队列(Running Queue)、等待队列(Waiting Queue)、挂起队列(Pending Queue),并管理三个队列中线程的切换,直到全部队列为空或出错而退出。
三、Nmap API
数据传递
nmap.luadoc是与nmap内部函数交互和数据结构化的API,API提供目标主机的详细信息例如端口状态和版本探测结果;同时API也提供与Nsock交互的接口,这样方便我们自己写NSE脚本与服务器交互,目前文件中共48个函数。
在脚本引擎中,用户可以轻松访问Nmap已经了解的有关目标主机的信息。该数据作为参数传递给NSE脚本的action方法,参数host和port是lua表,其中包含脚本执行的目标的信息。下面介绍每个表里面所含有的变量。
nmap使用注册表来共享信息,每个脚本之间共享nmap.registry,每个主机还有自己的注册表名为host.registry;在整个扫描会话中,全局注册表始终存在。脚本可以使用它,例如,存储稍后将由postrule脚本显示的值。机注册表仅在主机被扫描时存在。它们可以用于将信息从一个脚本发送到另一个脚本。例如:1)ssh-hostkey脚本的portrule收集SSH密钥指纹,并将其存储在全局nmap.registry中,以便稍后可以由postrule打印。2)ssl-cert脚本收集SSL证书并将其存储在每个主机注册表中,以便ssl-google-cert-catalog脚本可以使用它们,而无需再次连接到服务器。nmap.registry是全局的,因此key选择很重要;使用另一个脚本结果的脚本必须使用dependencies变量来声明它,以确保先前的脚本首先运行。
host.ip
host.name 通过dns反向查询的主机名,如果没查到则为空串
host.targetname
host.reason: 给出host处于现在这个状态的解释
host.reason_ttl
host.mac_addr
host.directly_connected
host.mac_addr_next_hop
host.mac_addr_src
host.interface
host.interface_mtu
host.bin_ip
host.bin_ip_src
host.times
host.traceroute port.number
port.protocol: 有效值为tcp、udp
port.service: 字符串表示的运行在端口号上的服务,该服务由服务探测阶段探测出,如果 port.version.service_dtype字段是table,那么Nmap基于端口号猜测服务;如果不是table,那么版本探测阶段能够确定是什么服务,这个字段的值被设定为port.version.name
port.reason: 字符串解释处于port.state状态的原因。
port.reason_ttl
port.version: 这个字段是一个表格,包含版本探测阶段返回的全部信息,包括:name;name_confidence;等,具体可参考官方文档版本探测章节。
port.state 参考:https://nmap.org/book/nse-api.htm
Network I/O API
require("nmap")
-- 简单的使用Nsock连接服务器的例子
local socket = nmap.new_socket()
socket:set_timeout()
try = nmap.new_try(function() socket:close() end)
try(socket:connect(host.ip, port.number))
try(socket:send("login"))
response = try(socket:receive())
socket:close()
除此之外还有receive_bytes方法,receive_lines方法,receive_buf方法,可查看nmap.luadoc文件
除了Network的方式还有行包连接的方式:参考https://nmap.org/book/nse-api.html
四、编写自己的脚本的建议
编写NSE脚本,需要根据Nmap规范编写description,author,license,categories,rule,action字段的内容,其中主要是action字段的编写;如果rule函数返回结果为真,那么执行编写的action函数。
The Rule
这部分决定是否执行action函数,A prerule or a postrule 类型的脚本总是执行;在端口规则脚本里面,NSE仅给我们当前扫描端口的信息,比如一个脚本要执行,但是必须保证当前端口开启并且113端口开启,为了检测113端口是否开启,我们使用nmap.get_port_state这个函数,如果113端口没有被扫描,函数将返回nil。
portrule = function(host, port)
local auth_port = { number=, protocol="tcp" }
local identd = nmap.get_port_state(host, auth_port)
return identd ~= nil
and identd.state == "open"
and port.protocol == "tcp"
and port.state == "open"
end
The Action
脚本首先连接到我们探测的端口,通过调用nmap.new_socket创建两个套接字选项。接下来,我们定义一个错误处理捕获功能,如果检测到故障,则关闭这些套接字。此时我们可以安全地使用诸如打开,关闭,发送和接收的对象方法来在网络套接字上操作。在这种情况下,我们调用connect来建立连接。 NSE的异常处理机制用于避免过多的错误处理代码。 try用来包围可能出错的代码,如果有任何问题,这将调用catch函数。如果两个连接成功,我们构造一个查询字符串并解析响应,最后返回解析结果。
action = function(host, port)
local owner = ""
local client_ident = nmap.new_socket()
local client_service = nmap.new_socket()
local catch = function()
client_ident:close()
client_service:close()
end
local try = nmap.new_try(catch)
try(client_ident:connect(host.ip, ))
try(client_service:connect(host.ip, port.number))
local localip, localport, remoteip, remoteport =
try(client_service:get_info())
local request = port.number .. ", " .. localport .. "\r\n"
try(client_ident:send(request))
owner = try(client_ident:receive_lines())
if string.match(owner, "ERROR") then
owner = nil
else
owner = string.match(owner,
"%d+%s*,%s*%d+%s*:%s*USERID%s*:%s*.+%s*:%s*(.+)\r?\n")
end
try(client_ident:close())
try(client_service:close())
return owner
end
五、参考文献
https://nmap.org/changelog.html#7.50 Nmap各版本更新内容
https://nmap.org/book/nse-tutorial.html NSE编写指南
https://nmap.org/book/nse-api.html Nmap API
https://nmap.org/ Nmap官网
Nmap脚本引擎原理的更多相关文章
- Nmap脚本文件分析(AMQP协议为例)
Nmap脚本文件分析(AMQP协议为例) 一.介绍 上两篇文章 Nmap脚本引擎原理 编写自己的Nmap(NSE)脚本,分析了Nmap脚本引擎的执行过程,以及脚本文件的编写,这篇文章将以解析AMQ ...
- Nmap源码分析(脚本引擎)
Nmap提供了强大的脚本引擎(NSE),以支持通过Lua编程来扩展Nmap的功能.目前脚本库已经包含300多个常用的Lua脚本,辅助完成Nmap的主机发现.端口扫描.服务侦测.操作系统侦测四个基本功能 ...
- nmap 使用脚本引擎进行扫描
1.下载nmap(nmap官网). 2.安装nmap. 3.编辑环境变量(windows下所需),保存.
- nmap脚本扫描使用总结
nmap的脚本默认目录为:/usr/share/nmap/scripts/ Nmap提供的命令行参数如下 -sC: 等价于--script=default,使用默认类别的脚本进行扫描 可更换其他类别 ...
- C#脚本引擎 CS-Script 之(三)——如何部署
本文不但介绍了CS-Script如何部署,还介绍了CS-Script的部署后面的原理,并用一个框图详细介绍了部署中的各种细节. 一.获取资源 1.从官网上下载编译好的csscript资源:cs-scr ...
- 脚本AI与脚本引擎
Scripted AI and Scripting Engines 脚本AI与脚本引擎 This chapter discusses some of the techniques you can us ...
- nmap脚本使用总结
0x00 前言: nmap的基本介绍和基本使用方法,在乌云知识库中已经有人提交过,讲的比较详细,在此文中就不再讲述. 具体链接:http://drops.wooyun.org/tips/2002 本文 ...
- nmap脚本nse的使用
nmap脚本(nse)使用总结 0x01 nmap按脚本分类扫描 nmap脚本主要分为以下几类,在扫描时可根据需要设置--script=类别这种方式进行比较笼统的扫描: auth: 负责处理鉴权证书( ...
- nmap脚本(nse)使用总结
nmap脚本主要分为以下几类,在扫描时可根据需要设置--script=类别这种方式进行比较笼统的扫描: auth: 负责处理鉴权证书(绕开鉴权)的脚本 broadcast: 在局域网内探查更多服务 ...
随机推荐
- Android的root学习
Android的内核就是Linux,所以Android获取root其实和Linux获取root权限是一回事儿.在Linux下获取root权限的时候就是执行sudo或者su,接下来系统会提示输入root ...
- [Git]06 如何提交空目录
git和 svn不同,仅仅跟踪文件的变动,不跟踪目录.所以,一个空目录,如果里面没有文件,即便 git add 这个目录,另外在别处 check out 的时候,是没有这个空目录的. 只跟踪文件 ...
- 蓝桥杯-四平方和-java
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...
- Ubuntu下如何解压各类文件
tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)---------------.gz解压1:gunzi ...
- linux服务器对外打包处理
案例描述 服务器遇到大流量攻击的处理过程.早上接到 IDC 的电话,说我们的一个网段 IP 不停的向外发包,应该是被攻击了,具体哪个 IP不知道,让我们检查一下. 按理分析及解决办法 首先我们要先确定 ...
- 工厂模式(Factory)和抽象工厂模式(Abstract Factory)
一.工厂模式(Factory):通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的,工厂方法让类的实例化推迟到子类 (1)涉及角色:抽象产品,具体产品,抽象创建者,具体创建者. ...
- Android码农如何一个星期转为iOS码农(不忽悠)
WeTest 导读 作为一个android客户端开发,如果你不懂点ios开发,怎么好意思说自己是客户端开发呢,本文讲解如何让android开发码农在一个星期上手IOS开发 --<记录自己IOS开 ...
- IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)
有热心的网友加我微信,时不时问我一些技术的或者学习技术的问题.有时候我回微信的时候都是半夜了.但是我很乐意解答他们的问题.因为这些年轻人都是很有上进心的,所以在我心里他们就是很优秀的,我愿意多和努力的 ...
- bash shell中测试命令
bash shell中测试命令 test命令提供了if-than语句中测试不同条件的途径.如果test命令中列出的条件成立,test命令就会退出并返回退出状态吗0 .这样if-than语句就与其他编程 ...
- php如何应对秒杀抢购高并发思路
我们常用QPS(Query Per Second,每秒处理请求数)来衡量一个web应用的吞吐率,解决每秒数万次的高并发场景,这个指标非常关键. 举个栗子:假设一个业务请求平均为100ms,同时系统内有 ...