https://nmap.org/nsedoc/lib/stdnse.html
这个模块中都是一些小而有用的功能,他们不足以独立成模块,所以集成在这个标准库里
函数名 | 功能介绍 |
---|---|
clock_ms () | 返回自纪元以来的当前时间(以毫秒为单位) |
clock_us () | 返回自纪元以来的当前时间(以微秒为单位) |
debug (level, fmt, ...) | 如果当前调试级别大于或等于给定级别,则打印格式化的调试消息。 |
format_mac (mac) | 将MAC地址格式化为以冒号分隔的十六进制字节。 |
format_output(status, data, indent) | 被弃用了 |
fromhex (hex) | 将十六进制字符串解码为原始字节 |
get_hostname(host) | 获取给定主机最可能的主机名。它可以是命令行中指定的目标,反向dns名称或简单的ip地址 |
get_script_args (..., Arguments) | 用来解析 --script-args 选项 |
get_timeout (host, max_timeout, min_timeout) | 返回主机的超时时间 |
make_buffer(socket, sep) | 这个就是一个迭代器,将socket接收到值根据 sep 进行分块,每次调用返回一块 |
module (name, ...) | 模拟Lua 5.1模块功能某些行为的模块功能 |
new_thread (main, ...) | 此功能使您可以创建工作线程,这些工作线程可以与脚本线程并行执行网络任务 |
output_table () | 返回一个表,该表按插入顺序保留元素,就是最后的输出表 |
parse_timespec(timespec) | 解析持续时间规范,该规范是一个数字,后跟一个单位,并返回秒数 |
pretty_printer (obj, printer) | 漂亮的Lua对象打印机 |
print_debug (level, fmt, ...) | 不推荐使用的debug()版本,目前保留该版本,以防止脚本ID被打印两次。脚本应使用debug()且不要传递SCRIPT_NAME |
print_verbose (level, fmt, ...) | verbose()的不推荐使用的版本,保留至今,以防止脚本ID被打印两次。脚本应使用verbose()且不传递SCRIPT_NAME |
registry_add_array(subkeys, value, allow_duplicates) | 将一个值添加到registry的array中,并在必要时创建所有子项 |
registry_add_table(subkeys, key, value, allow_duplicates) | 这个是向 registry 的 table 中添加一个键值对 |
registry_get(subkeys) | 检查一个子键列表中每一层子键是不是都存在,如果不存在返回 nil |
seeall (env) | 更改环境以加载全局变量 |
silent_require () | 将 require 函数报错隐藏的执行 |
sleep (t) | 睡眠一段时间 |
string_or_blank(string, blank) | 判断如果是字符串为返回本身,不是返回 或者给定的参数 |
tobinary (n) | 转化成二进制数 |
tohex (s, options) | 转化成十六进制数 |
tooctal (n) | 转化成八进制数 |
verbose (level, fmt, ...) | 如果当前详细级别大于或等于给定级别,则打印格式化的详细消息 |
debug 函数为不定长参数,第一个参数为打印等级
如果当前调试级别大于或等于给定级别,则打印格式化的调试消息。这个函数是 nmap.log_write 的一个简单封装,第一个参数是打印等级,其余参数都是由 string.format 函数进行处理
如果已知,则输出包括一些基于上下文的信息:脚本标识符和目标ip /端口(如果有)。如果调试级别至少为2,则还将打印基本线程标识符以及它是工作线程还是主线程
不推荐使用
verbose 是不定长参数
如果当前详细级别大于或等于给定级别,则打印格式化的详细消息。
make_buffer 函数有两个参数:socket, sep ,socket 参数是一个socket变量,sep为分隔符,返回值为读取到的块的数据以及错误信息
在http的脚本中没有用到这个函数的,在所有的脚本中,这个函数也用的较少,我们看一下吧
可以看到大家调用的时候sep参数基本都是 "\n"、"\r"、"\r\n"、"\r?\n",可以看到是用作获取相关分隔符分隔后的数据块
tobinary 只有一个参数,待转换的数字,返回值为二进制字符串
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo = 35
local result = stdnse.tobinary(demo)
output.restype = type(result)
output.result = result
return output
end
测试一下
tooctal 只有一个参数,这个参数为一个数字,返回一个八进制格式数字的字符串
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo = 64
local result = stdnse.tooctal(demo)
output.restype = type(result)
output.result = result
return output
end
测试一下
可以看到将十进制的 64 转换为 八进制的 100
tohex 函数有两个参数:s, options,返回值为16进制形式的字符串
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo1 = "abc"
local demo2 = 123456
output.result_abc_sep_null_group_null = stdnse.tohex(demo1)
output.result_abc_sep_colon_group_null = stdnse.tohex(demo1, {separator = ":"})
output.result_abc_sep_colon_group_3 = stdnse.tohex(demo1, {separator = ":", group = 3})
output.result_123456_sep_null_group_null = stdnse.tohex(demo2)
output.result_123456_sep_colon_group_null = stdnse.tohex(demo2, {separator = ":"})
output.result_123456_sep_colon_group_3 = stdnse.tohex(demo2, {separator = ":", group = 3})
output.restype = type(output.result_123456_sep_colon_group_3)
return output
end
测试一下
可以看到, abc 被转换为 616263, 添加了分隔符后会按照默认的每两个字符来进行按照分隔符进行分隔返回,如果设置了分隔尺寸,则按照相关尺寸进行分隔。
fromhex 只有一个参数,为16进制的字符串,该字符串可以包含任意数量的空格和大写或小写十六进制数字。十六进制数字必须是偶数,因为要用2个十六进制数字来构成一个字节。
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo = "534364"
local result = stdnse.fromhex(demo)
output.restype = type(result)
output.result = result
return output
end
测试一下
format_mac 只有一个参数,参数为MAC地址二进制的字符串,比如 host.mac_addr, 返回值为 XX:XX:XX:XX:XX:XX 形式的字符串
上面这是 Nmap官方库的注释里写的,但是经过我的测试并不是这样,其实参数 MAC 是一个十进制数,假如我想得到一个正确的mac,我们需要将这个不带冒号的mac地址转换为10进制数,之后作为参数提交
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo = 20526534579951
local result = stdnse.format_mac(demo)
output.restype = type(result)
output.rawrest = demo
output.result = result
return output
end
测试一下
string_or_blank 有两个参数,string, blank,这个函数就是用来判断第一个参数是否为nil或者"" ,如果不是空则返回字符串本身,是空则返回第二个参数,第二个参数没有设置的时候返回 "" 字符串
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local demo1 = "test"
local result1 = stdnse.string_or_blank(demo1)
local demo2 = ""
local result2 = stdnse.string_or_blank(demo2, "this is blank")
output.restype = type(result1)
output.demo1 = demo1
output.result1 = result1
output.demo2 = demo2
output.result2 = result2
return output
end
测试一下
解析持续时间规范,该规范是一个数字,后跟一个单位,并返回秒数。
parse_timespec函数只有一个参数 timespec,这个参数是一个规范字符串,可以是以下格式:
如果给定参数不是规范字符串,则返回 nil
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local res_10 = stdnse.parse_timespec("10")
local res_10ms = stdnse.parse_timespec("10ms")
local res_10s = stdnse.parse_timespec("10s")
local res_10m = stdnse.parse_timespec("10m")
local res_10h = stdnse.parse_timespec("10h")
output.restype = type(res_10h)
output.res_10 = res_10
output.res_10ms = res_10ms
output.res_10s = res_10s
output.res_10m = res_10m
output.res_10h = res_10h
return output
end
测试一下
返回自纪元以来的当前时间(以毫秒为单位),无参数
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local result = stdnse.clock_ms()
output.restype = type(result)
output.result = result
return output
end
测试一下
返回自纪元以来的当前时间(以微秒为单位), 无参数
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local result = stdnse.clock_us()
output.restype = type(result)
output.result = result
return output
end
测试一下
get_script_args 函数用来解析 --script-args ,不定长参数
这个函数非常重要且复杂,可能是我们以后经常用到的
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local url = require "url"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local functest_arg1, functest_arg2, functest_arg3, functest_arg4, functest_arg5 = stdnse.get_script_args("functest.arg1", "functest.arg2", "functest.arg3", "functest.arg4", "functest.arg5")
output.functest_arg1_type = type(functest_arg1)
output.functest_arg1_result = functest_arg1
output.functest_arg2_type = type(functest_arg2)
output.functest_arg2_result = functest_arg2
output.functest_arg3_type = type(functest_arg3)
output.functest_arg3_result = functest_arg3
output.functest_arg4_type = type(functest_arg4)
output.functest_arg4_result = functest_arg4
output.functest_arg4_type = type(functest_arg5)
output.functest_arg4_result = functest_arg5
return output
end
这里我定义了functest有五个参数,之后分别进行不同情况的测试
我们通过 --script-args 来进行参数传递,相关参数传递的值分别为
得到的结果如下:
可以得出结论
通过以上结果可以事先做好类型定义以及异常处理
获取给定主机的最可能的主机名。它可以是命令行中指定的目标,反向dns解析的名称或就是ip地址。
get_hostname 只有一个参数,参数为默认的 host, 返回值为最佳的 hostname 值
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local http = require "http"
local stdnse = require "stdnse"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local options = {header={}}
options["header"]["User-Agent"] = "function post test "
--local data = http.get(host, port, "/", options)
--local contain, content = http.response_contains(data,'[a-z](.+?)',false)
local result = stdnse.get_hostname(host)
output.restype = type(result)
output.result = result
return output
end
使用百度测试一下
可以看到返回值为字符串类型的hostname
registry_get 函数只有一个参数 subkeys ,是一个表,即子键
这个表中存放着要查询的子键,如果所有层子键都存在则返回最下层的值,如果有一个不存在就返回 nil
registry_exists 函数有三个参数,subkeys, key, value
如果key,value键值对存在,那么返回 true,否则返回false
registry_add_array有三个参数:subkeys, value, allow_duplicates ,没有返回值
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local http = require "http"
local stdnse = require "stdnse"
local nmap = require "nmap"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local result = stdnse.registry_add_array({'192.168.1.100', 'www', '80', 'pages'}, 'index.html')
output.restype = type(result)
output.result = result
output.reg = nmap.registry
return output
end
这里我们将返回值打印,将运行后的 nmap.registry 打印
从结果可以看到,这个函数并没有返回值,运行后的 nmap.registry 按照 subkeys的层级关系建立了一个数组,并将 value 的值存储到了其中
registry_add_table 与 registry_add_array 相似,有四个参数 subkeys, key, value, allow_duplicates,这个函数是向 nmap.registry 中的表中插入键值对
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local http = require "http"
local stdnse = require "stdnse"
local nmap = require "nmap"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local result = stdnse.registry_add_table({'192.168.1.100', 'www', '80', 'pages'}, 'index_page','index.html')
output.restype = type(result)
output.result = result
output.reg = nmap.registry
return output
end
测试一下
这个函数应该就不用说了,咱们的每个代码都有这个,这就是一个输出表,会按照插入数据的顺序进行显示
pretty_printer 这个函数在nse中用的极少,可以使用下面命令进行查询
可以看到没有script 使用了这个函数
get_timeout 函数有三个参数:host, max_timeout, min_timeout ,返回一个以毫秒为单位的适合传递给 set_timeout 的数字
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by root.
--- DateTime: 2020/1/2 上午9:39
---
local http = require "http"
local stdnse = require "stdnse"
local nmap = require "nmap"
description = [[
This is a test for http.lua's functions
]]
author = "test94"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default"}
prerule = function()
print("functest running")
end
portrule = function () return true end --shortport.http
action = function(host, port)
local output = stdnse.output_table()
local result = stdnse.get_timeout(host, 4000, 1000)
output.restype = type(result)
output.result = result
output.host_timeout = host.times.timeout
return output
end
找一个美国的主机测试一下