编写自己的nmap脚本

  1. 前言
  2. 环境准备
  3. 需要学的
  4. 参考文章
  5. 编写

前言

nmap有很多自己的脚本,在渗透的时候都能帮上忙,那么如何自己写一个呢?
timg?image&quality=80&size=b9999_10000&sec=1562749002996&di=b9b3b409c2795b275891076ff7d1c944&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2Fattachments2%2Fday_120501%2F1205012009f594464a3d69a145.jpg

环境准备

nmap
lua

当然你也可以用kali(废话)

需要学的

lua基础 ->菜鸟教程
   ->基本知识(变量)
   ->数据类型
   ->函数
   ->表
   ->数组
   ->字符串
   ->引入第三方模块
   ->文件操作

nmap内置API调用->官方文档
  ->nmap脚本的规范
  ->内置API如何去使用

参考文章

参考文章:
nmap API手册大全:
https://nmap.org/nsedoc/lib/

Nmap编写自定义脚本的规则:
https://nmap.org/book/nse-script-format.html
https://nmap.org/book/nse-tutorial.html#nse-tutorial-rule

来自车王的文章:
Nmap脚本编写 - 知乎

概念图:
ZcnsU0.png

编写

首先得导入nmap的内置模块
PS:你可以看上面的API手册来导入你要导入的lua脚本

local http=require "http"
local shortport=require "shortport"
local stdnse=require "stdnse"
local string=require "string"
local vulns=require "vulns"

在漏洞说明里面写点东西
ZcueZn.png

description=[[
Grabbing a Site for Subdomain Names
]]

作者信息与脚本分类

author="Jiushi" --作者
license="Same as Nmap--See https://nmap.org/book/man-legal.html" --nmap证书
categories={"default"} --脚本的分类

规则函数

portrule=function(host,port)
    set_port=stdnse.get_script_args("port") --选择参数
    if (type(set_port)~="nil") then
        local auth_port={number=tonumber(set_port),protocol="tcp"}
        local identd=nmap.get_port_state(host,auth_port)
        return identd.number==tonumber(set_port) and identd.state=="open" and port.protocol=="tcp"

    end
end


PS:portrule函数是在每一个端口运行一次这个脚本,所以用的时候得指定脚本

行动函数->action

action=function(host,port)
    local ht=stdnse.get_script_args("protocol")
    local path={"/console/login/LoginForm.jsp","/wls-wsat/CoordinatorPortType","/_async/AsyncResponseService","/ws_utc/config.do","/uddiexplorer"}
    local urls=string.format("%s://%s",ht,host['ip'])
    local jiances=jianche(urls,path) --调用一个自定义函数
    return jiances

end


官方写的例子->

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, 113))
        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(1))

        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

链接到此文章:传送门

完整代码:

--author:jiushi
--date:19-7-10
--time:早上9:28

local http=require "http"
local shortport=require "shortport"
local stdnse=require "stdnse"
local string=require "string"
local vulns=require "vulns"

description=[[
Weblogic path scanning
]]

--nmap --script=weblogic_query --script-args port=<weblogic_port>,protocol=<http/https> IP
--Starting Nmap 7.70 ( https://nmap.org ) at 2019-07-10 12:59 CST
--Nmap scan report for 192.168.241.140
--Host is up (0.00021s latency).

--PORT     STATE SERVICE
--7001/tcp open  afs3-callback
--| weblogic_query:
--|   [200]: http://192.168.241.140:7001/console/login/LoginForm.jsp
--|   [200]: http://192.168.241.140:7001/wls-wsat/CoordinatorPortType
--|   [200]: http://192.168.241.140:7001/_async/AsyncResponseService
--|_  [200]: http://192.168.241.140:7001/uddiexplorer

--Nmap done: 1 IP address (1 host up) scanned in 2.45 seconds


author="Jiushi"
license="Same as Nmap--See https://nmap.org/book/man-legal.html"
categories={"default"}

portrule=function(host,port)
    set_port=stdnse.get_script_args("port")
    if (type(set_port)~="nil") then
        local auth_port={number=tonumber(set_port),protocol="tcp"}
        local identd=nmap.get_port_state(host,auth_port)
        return identd.number==tonumber(set_port) and identd.state=="open" and port.protocol=="tcp"

    end
end

function jianche(url,path)
    local demo={}
    local headers={header={}}
    headers['header']['User-Agent']="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
    for p in pairs(path) do
        local urls=string.format("%s:%s%s",url,set_port,path[p])
        local request=http.get_url(urls,headers) --发送get请求,有路径的url得用get_url()请求否则会报错
        if (request.status==200 and string.match(request.body,"Not Found")==nil) then
            table.insert(demo,string.format("[%s]: %s",request.status,urls))
        end

    end
    return demo
end

action=function(host,port)
    local ht=stdnse.get_script_args("protocol")
    local path={"/console/login/LoginForm.jsp","/wls-wsat/CoordinatorPortType","/_async/AsyncResponseService","/ws_utc/config.do","/uddiexplorer"}
    local urls=string.format("%s://%s",ht,host['ip'])
    local jiances=jianche(urls,path)
    return jiances

end

PS:像官方文档中选项之类的东西,得用二维数组来设置
ZcKjAI.png

测试效果:
ZcMavD.png

ZcMcPP.png

动态gif
ZcQtds.gif

END


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:编写自己的nmap脚本

本文作者:九世

发布时间:2019-07-10, 13:05:03

最后更新:2019-07-10, 14:09:32

原始链接:http://jiushill.github.io/posts/81575c3f.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录