0x01
记得我们上次写的脚本吗?脚本内容的portrule中是这样的:
return port.protocol == “tcp” and port.number == 80 and port.service == “http” and port.state == “open”
有没有想过port的protocol,number,service,state是哪儿来的?
这些其实就是nmap提供给我们的API。API的核心功能就是向脚本提供关于主机和端口的信息,例如名字解析,主机和端口的状态、服务发现等。
Nmap中的引擎会向脚本传递如下两个Lua table类型的参数:host table,port table
这两个table中包含了目标主机的host和port信息。
先来看看host table,包括的字段有
每个字段的具体含义可以去这里查看:
https://nmap.org/book/nse-api.html
这里就稍微介绍些host.os,它是操作系统匹配表的数组。操作系统匹配由一个可读的名称和一系列操作系统类组成。每个操作系统类由一个供应商、操作系统系列、操作系统生成、设备类型和该类的一组CPE条目组成
格式如下
如果能与nmap-os-db(nmap的主机指纹库)中的条目匹配,则会返回类似如下的详细信息
我们现在以mac_addr为例,看看通过它能得到什么信息。它表示目标的mac地址,只有处于同一子网的设备,这个参数才有效。
我们创建一个名为apitest.nse的脚本,因为是host表的字段,所以执行规则是hostrule
我们想要得到的是mac_addr,所以在action中return回host.mac_addr
完整代码如图所示
保存并update script db
测试结果如下
可以看到打印出了mac地址,可以看到这个mac地址和我们平时见到的格式不太一样。因为通过host.mac_addr获取的mac地址是二进制编码的,我们要转换成字符串,需要引入stdnse库,stdnse包中有一个format_mac函数,能够将host.mac_addr转换成字符串
所以在nse脚本开头加上
action的return部分改为
完整代码如下
运行结果如图
此时得到了可读的mac地址了
host的其他字段请自行根据上述的方法测试。
。
0x02
接下来再看看port。Port的字段比较少,包括number,protocol,service,verison,state等。
以之前写的脚本用到的
“return port.protocol == “tcp” and port.number == 80 and port.service == “http” and port.state == “open”
为例
protocol标志了目标端口的类型,为tcp或udp
number就是目标端口的编号
service即端口上运行的服务
state表示端口上运行的状态
脚本就是通过判断80端口开放,运行这http,然后打印出this is a webserver的
同样也写一个脚本测试一下
需要注意,这时应该是portrule
以及action是返回port.protocol
完整代码
测试结果如图
可以看到分别打印出了对应的protocol,上图中都是tcp
0x03
前面我们在格式化host.mac_addr返回的mac地址时,使用了stdnse这个库文件,接下来我们来学习nse中的库文件
自带的库文件都在/usr/share/nmap/nselib,Halcyon列出来了
我们切换到对应的路径下,自己写一个库文件试试
这个库的功能是打印出某端口是否开放
我们先声明所需的库文件”stdnse”,它保存了一些用于输入的函数
然后定义一个函数,它需要一个参数,将参数传递给stdnse库,用于格式化输出format函数
保存并退出
接下来写个nse,在其中导入这个库文件
调用这个函数
这里PrintPort就是我们在mylib.lua这个库中定义的函数
保存并update scriptdb
运行测试如下
。