Nmap NSE 缺陷
今天在编写 Nmap 脚本的时候发现了一个小缺陷:
Nmap 判定扫描结果为 filtered 的时候,就不会进入 portrule 了
首先给大家看一下代码
可以看到,我在 portrule 处直接返回了 true ,所以按照规则来说,无论端口是什么规则,都会执行,但是结果如下
可以看到:
- 在 open 状态下,prerule、portrule以及 action 中的代码都执行了
- 在 filtered 状态下,prerule 内容执行了,打印了 Weblogic Console Searching ...
但是,action 中代码并没有执行
我们简单调试一下,在 portrule 中输出一下:
测试一下
重新测试两次,刚好出现了open 和 filtered 的情况
- open 状态下,打印了 portrule is here! ,并且执行了 action 中的扫描内容
- filtered 状态下,执行了 prerule ,但是没有执行 portrule
从以上这些现象说明,在 filtered 状态下是不会执行到 portrule 这个规则的
但是这样的话,shortport 中的 port_or_service 函数的最后一个状态参数也没有意义了呀(这个现在还没在公众号发布,后续会发布)
所以我猜应该是我理解有问题,不然那么多写脚本的大哥肯定会发现的
在portrule 之前还有 hostrule, 我们看一下filtered 状态下会执行到这里吗?
测试一下
测试了好久终于出现了一个 open 一个filtered 的对比图
- open 状态下,执行了两次 action 中的代码
- filtered 状态下,进入了 hostrule 中,执行了其中的代码(打印了 hostrule is here!)
以上情况说明 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
测试一下
这回正常了
总结如下 :
- 端口状态为 filtered 状态下,是不会执行 portrule 的
- port 对象是在 portrule 阶段被创建的,无法使用在 hostrule 阶段
- Nmap 对于端口检测很飘忽,得多测几次
那么问题又来了: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
分别测试一下
可以看到
- 加上 -Pn 时可以发现主机存活,可以执行 prerule、hostrule 和 postrule
- 不加 -Pn 无法发现主机存活,也无法执行 hostrule,可以执行 prerule, postrule
总结如下 :
- 端口状态为 filtered 状态下,是不会执行 portrule 的
- port 对象是在 portrule 阶段被创建的,无法使用在 hostrule 阶段的 action 代码中
- Nmap执行 NSE 是分阶段的,伴随着扫描的主机存活、端口开放的不同阶段进入不同的规则
- Nmap 对于端口检测很飘忽,得多测几次
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ESP8266和ROS收发消息读取模拟量控制LED亮度
- 纯 CSS 实现下拉菜单尖角图标(实心+空心)
- 3分钟短文:书接上回,Laravel数据库迁移的那些个小技巧
- 解密 Docker 挂载文件,宿主机修改后容器里文件没有修改
- SAP Spartacus的单元测试目录结构
- 突击并发编程JUC系列-并发工具 CyclicBarrier
- 详解 | Linux系统是如何实现存储并读写文件的?
- Angular单元测试的一个错误消息
- Python进行特征提取
- dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 的属性作用
- Java 对象相关面试题
- 【每日一题】【vue2源码学习】VUE中模版编译原理
- 【每日一题】【vue2源码学习】对VUE响应式数据的理解
- ApacheCN 深度学习译文集 2020.9
- 当Docker遇到Intellij IDEA,再次解放了生产力~