Nmap NSE 库分析 >>> url

时间:2022-07-23
本文章向大家介绍Nmap NSE 库分析 >>> url,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

编写WEB渗透脚本时候URL库基本就是组合 url 必备的了,非常方便


https://nmap.org/nsedoc/lib/url.html

0x00 简介

URI解析、组合和相对URL解析

URL表是一个具有以下字段的表:

  • scheme
  • fragment
  • query
  • params
  • authority
  • userinfo
  • path
  • port
  • password
scheme://userinfo@password:authority:port/path;params?query#fragment

0x01 方法

absolute (base_url, relative_url)

根据给定的基础url和相对url,组合出绝对路径进行返回

build (parsed)

Rebuilds a parsed URL from its components.

build_path (parsed, unsafe)

将路径片段组合为一个字符串路径,转义受保护的字符,返回 path 字符串

build_query (query)

将一个表中的数据组合为一个查询字符串,比如 "name=admin&pass=whoami"

escape (s)

将二进制字符串编码为转义的十六进制表示形式。

get_default_port (scheme)

通过http或https获取默认的端口

get_default_scheme (port)

根据端口获取默认的协议

parse (url, default)

将一个url按照各个部分分割为一个表

parse_path (path)

将一个path转换,并且进行转义

parse_query (query)

将一个请求字符串转换为 name/value 形式

unescape (s)

将一个16进制的字符串进行解密,并返回

0x02 方法调用实战

0x001 absolute

absolute 函数有两个参数: base_url, relative_url

---
--- 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 base_url = "/admin/"
    local relative_url = "./test/pwd/a.php"
    local result = url.absolute(base_url, relative_url)
    output.restype = type(result)
    output.result = result
    return output
end

本地nc监听80简单测试

可以看到返回值类型是 string ,值为组合后的绝对路径

0x002 parse

这个函数有两个参数:

  • url 一个完整的url
  • default 表明每个字段默认值得表,但是在调用时候通常不用
---
--- 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 relative_url = "https://www.baidu.com/test/pwd/a.php"
    local result = url.parse(relative_url, {query="?id=1&pwd=1"})
    output.restype = type(result)
    output.result = result
    return output
end

本次nc 监听80测试

可以看到返回一个表,表中字段众多,我们自定义默认query 值也生效了

0x003 build

build 函数只有一个参数,就是parse后的表

---
--- 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 relative_url = "https://www.baidu.com/test/pwd/a.php"
    local result = url.parse(relative_url, {query="?id=1&pwd=1"})
    local result = url.build(result)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到build 函数帮助我们把表中的各个字段组合起来了,并且以字符串的形式进行了返回

0x004 parse_path

parse_path 函数只有一个参数,path,是一个路径字符串

---
--- 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 query_table = {}
    local path_str = "/admin/pwd/index.php?pwd=true"
    local result = url.parse_path(path_str)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

0x005 build_path

这个函数有两个参数

  • query
  • unsafe boolean类型参数,true 为不转义危险字符,false为转义危险字符
---
--- 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 relative_url = "https://www.baidu.com/test/pwd/a.php"
    local result = url.parse(relative_url, {query="?id=1&pwd=1"})
    local result = url.build_path({"/admin", "test","pwd=1&a=2"}, false)
    output.restype = type(result)
    output.result = result
    return output
end

这里选择转义安全字符,测试结果如下

可以看到,返回值为字符串类型

0x006 parse_query

parse_query 函数只有一个参数,为参数字符串

---
--- 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 query_str = "pwd=true&debug=1"
    local result = url.parse_query(query_str)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到返回一个表,表中key为参数,value为参数值

0x007 build_query

build_query 函数只有一个参数

---
--- 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 query_tab = {}
    query_tab['admin']='1'
    query_tab['pass']='2'
    local result = url.build_query(query_tab)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到 build_query 与 parse_query 正好是相反的

0x008 get_default_port

get_default_port 只有一个参数,就是给定的协议

---
--- 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 scheme = "https"
    local result = url.get_default_port(scheme)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到返回值是一个数字,https默认为443

0x009 get_default_scheme

get_default_scheme 这个函数只有一个参数,就是端口

---
--- 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 g_port = 80
    local result = url.get_default_scheme(g_port)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到,结果是协议名字符串

0x0010 escape

escape 只有一个参数,需要转义的字符串

---
--- 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 str_line  = 'index?a=pwd&c="ok"'
    local result = url.escape(str_line)
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到返回值为被转义后的字符串

0x0011 unescape

解密被转义的字符串

---
--- 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 = url.unescape("index%3fa%3dpwd%26c%3d%22ok%22")
    output.restype = type(result)
    output.result = result
    return output
end

测试结果如下:

可以看到返回值为解密后字符串

作为一个搞安全的,肯定要测试一下双层url编码能解码到哪一步啦

---
--- 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 = url.unescape("index%253fa%253dpwd%2526c%253d%2522ok%2522")
    output.restype = type(result)
    output.result = result
    return output
end

这回使用双层 url 编码,结果为

可以看到,只做一层url解码