今天在编写 Nmap 脚本的时候发现了一个小缺陷:
Nmap 判定扫描结果为 filtered 的时候,就不会进入 portrule 了
首先给大家看一下代码
可以看到,我在 portrule 处直接返回了 true ,所以按照规则来说,无论端口是什么规则,都会执行,但是结果如下
可以看到:
但是,action 中代码并没有执行
我们简单调试一下,在 portrule 中输出一下:
测试一下
重新测试两次,刚好出现了open 和 filtered 的情况
从以上这些现象说明,在 filtered 状态下是不会执行到 portrule 这个规则的
但是这样的话,shortport 中的 port_or_service 函数的最后一个状态参数也没有意义了呀(这个现在还没在公众号发布,后续会发布)
所以我猜应该是我理解有问题,不然那么多写脚本的大哥肯定会发现的
在portrule 之前还有 hostrule, 我们看一下filtered 状态下会执行到这里吗?
测试一下
测试了好久终于出现了一个 open 一个filtered 的对比图
以上情况说明 filtered 状态下执行流程会停留在 hostrule 或者说 跳过 portrule
既然都整到这里了,也不差一个 postrule 了,把hostrule给注释了,免得有不必要的影响,反正已经确定了hostrule 的情况
测试一下
可以看到,prerule 和 postrule 都执行了,所以说从结果来说,遇到端口 filtered 会跳过 portrule
看似情况都清晰了,但还有一个小问题,为啥在 hostrule 中调用 action 中的代码会报错,而 postrule 中不会
我们使用 -d 参数来追踪一下
local stdnse = require "stdnse"
local shortport = require "shortport"
local http = require "http"
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("Weblogic Console Searching ... ")
end
hostrule = function()
print("hostrule is here!")
return true
end
--portrule = function()
-- print("portrule is here!")
-- return true
--end-- shortport.port_or_service(7001, {"http", "https", "afs3-callback"}, "tcp")-- {"open", "filtered", "open|filtered"})
postrule = function()
print("postrule is here!")
end
action = function(host, port)
print('I am action')
local output = stdnse.output_table()
output.SCRIPT_NAME = SCRIPT_NAME
output.SCRIPT_TYPE = SCRIPT_TYPE
output.SCRIPT_PATH = SCRIPT_PATH
-- 配置 http options
local options = {header = {}}
options["header"]["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36"
local pipelines = http.pipeline_add("/console/", nil, nil, "GET")
local pipelines2 = http.pipeline_add("/console/login/LoginForm.jsp", nil, pipelines,"GET")
local pipelines3 = http.pipeline_add("/console/login/LoginfdForm.jsp", nil, pipelines2,"GET")
local result = http.pipeline_go(host, port, pipelines3)
output.result = {}
--for _, v in pairs(result) do
-- output.result[#result+1] = v
--end
-- 目前存在同一个数据包中发两个http包的情况,不知道因为啥,待处理
output.result[#output.result+1] = result[1]["status"]
output.result[#output.result+1] = result[2]["status"]
output.result[#output.result+1] = result[3]["status"]
return output
end
测试一下
其实很好理解,在 hostrule 这里,只有host 这个对象,还没有 port 这个对象,所以会报错
我们将 port 直接替换成 7001 进行测试
local stdnse = require "stdnse"
local shortport = require "shortport"
local http = require "http"
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("Weblogic Console Searching ... ")
end
hostrule = function()
print("hostrule is here!")
return true
end
--portrule = function()
-- print("portrule is here!")
-- return true
--end-- shortport.port_or_service(7001, {"http", "https", "afs3-callback"}, "tcp")-- {"open", "filtered", "open|filtered"})
postrule = function()
print("postrule is here!")
end
action = function(host)
print('I am action')
local output = stdnse.output_table()
output.SCRIPT_NAME = SCRIPT_NAME
output.SCRIPT_TYPE = SCRIPT_TYPE
output.SCRIPT_PATH = SCRIPT_PATH
-- 配置 http options
local options = {header = {}}
options["header"]["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36"
local pipelines = http.pipeline_add("/console/", nil, nil, "GET")
local pipelines2 = http.pipeline_add("/console/login/LoginForm.jsp", nil, pipelines,"GET")
local pipelines3 = http.pipeline_add("/console/login/LoginfdForm.jsp", nil, pipelines2,"GET")
local result = http.pipeline_go(host, 7001, pipelines3)
output.result = {}
--for _, v in pairs(result) do
-- output.result[#result+1] = v
--end
-- 目前存在同一个数据包中发两个http包的情况,不知道因为啥,待处理
output.result[#output.result+1] = result[1]["status"]
output.result[#output.result+1] = result[2]["status"]
output.result[#output.result+1] = result[3]["status"]
return output
end
测试一下
这回正常了
总结如下 :
那么问题又来了:hostrule 是不是也存在被跳过的状态(不执行)
正好之前的目标是 ping 不通的,只有加 -Pn 参数才能确定主机是否存活,刚好来测试一下,加与不加 -Pn 参数对 hostrule 的执行会不会有什么影响
代码如下
local stdnse = require "stdnse"
local shortport = require "shortport"
local http = require "http"
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("Weblogic Console Searching ... ")
end
hostrule = function()
print("hostrule is here!")
return true
end
--portrule = function()
-- print("portrule is here!")
-- return true
--end-- shortport.port_or_service(7001, {"http", "https", "afs3-callback"}, "tcp")-- {"open", "filtered", "open|filtered"})
postrule = function()
print("postrule is here!")
end
action = function(host)
print('I am action')
local output = stdnse.output_table()
output.SCRIPT_NAME = SCRIPT_NAME
output.SCRIPT_TYPE = SCRIPT_TYPE
output.SCRIPT_PATH = SCRIPT_PATH
-- 配置 http options
local options = {header = {}}
options["header"]["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3100.0 Safari/537.36"
local pipelines = http.pipeline_add("/console/", nil, nil, "GET")
local pipelines2 = http.pipeline_add("/console/login/LoginForm.jsp", nil, pipelines,"GET")
local pipelines3 = http.pipeline_add("/console/login/LoginfdForm.jsp", nil, pipelines2,"GET")
local result = http.pipeline_go(host, 7001, pipelines3)
output.result = {}
--for _, v in pairs(result) do
-- output.result[#result+1] = v
--end
-- 目前存在同一个数据包中发两个http包的情况,不知道因为啥,待处理
output.result[#output.result+1] = result[1]["status"]
output.result[#output.result+1] = result[2]["status"]
output.result[#output.result+1] = result[3]["status"]
return output
end
分别测试一下
可以看到
总结如下 :