mirror of
https://github.com/nmap/nmap.git
synced 2025-12-14 19:59:02 +00:00
Move url-encoding to url.build_query
patch from nnposter: http://seclists.org/nmap-dev/2014/q3/427
This commit is contained in:
@@ -319,7 +319,8 @@ end
|
|||||||
-- This function takes a <code><query></code> of the form
|
-- This function takes a <code><query></code> of the form
|
||||||
-- <code>"name1=value1&name2=value2"</code>
|
-- <code>"name1=value1&name2=value2"</code>
|
||||||
-- and returns a table containing the name-value pairs, with the name as the key
|
-- and returns a table containing the name-value pairs, with the name as the key
|
||||||
-- and the value as its associated value.
|
-- and the value as its associated value. Both the name and the value are
|
||||||
|
-- subject to URL decoding.
|
||||||
-- @param query Query string.
|
-- @param query Query string.
|
||||||
-- @return A table of name-value pairs following the pattern
|
-- @return A table of name-value pairs following the pattern
|
||||||
-- <code>table["name"]</code> = <code>value</code>.
|
-- <code>table["name"]</code> = <code>value</code>.
|
||||||
@@ -333,9 +334,11 @@ function parse_query(query)
|
|||||||
query = string.gsub(query, ">", ">")
|
query = string.gsub(query, ">", ">")
|
||||||
|
|
||||||
local function ginsert(qstr)
|
local function ginsert(qstr)
|
||||||
local first, last = string.find(qstr, "=")
|
local pos = qstr:find("=", 1, true)
|
||||||
if first then
|
if pos then
|
||||||
parsed[string.sub(qstr, 0, first-1)] = string.sub(qstr, first+1)
|
parsed[unescape(qstr:sub(1, pos - 1))] = unescape(qstr:sub(pos + 1))
|
||||||
|
else
|
||||||
|
parsed[unescape(qstr)] = ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -355,18 +358,19 @@ end
|
|||||||
---
|
---
|
||||||
-- Builds a query string from a table.
|
-- Builds a query string from a table.
|
||||||
--
|
--
|
||||||
-- This is the inverse of <code>parse_query</code>.
|
-- This is the inverse of <code>parse_query</code>. Both the parameter name
|
||||||
|
-- and value are subject to URL encoding.
|
||||||
-- @param query A dictionary table where <code>table['name']</code> =
|
-- @param query A dictionary table where <code>table['name']</code> =
|
||||||
-- <code>value</code>.
|
-- <code>value</code>.
|
||||||
-- @return A query string (like <code>"name=value2&name=value2"</code>).
|
-- @return A query string (like <code>"name=value2&name=value2"</code>).
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
function build_query(query)
|
function build_query(query)
|
||||||
local qstr = ""
|
local qstr = {}
|
||||||
|
|
||||||
for i,v in pairs(query) do
|
for i,v in pairs(query) do
|
||||||
qstr = qstr .. i .. '=' .. v .. '&'
|
qstr[#qstr+1] = escape(i) .. '=' .. escape(v)
|
||||||
end
|
end
|
||||||
return string.sub(qstr, 0, #qstr-1)
|
return table.concat(qstr, '&')
|
||||||
end
|
end
|
||||||
|
|
||||||
return _ENV;
|
return _ENV;
|
||||||
|
|||||||
@@ -97,14 +97,6 @@ local function generate_safe_postdata(form)
|
|||||||
return postdata
|
return postdata
|
||||||
end
|
end
|
||||||
|
|
||||||
local function generate_get_string(data)
|
|
||||||
local get_str = {"?"}
|
|
||||||
for name,value in pairs(data) do
|
|
||||||
get_str[#get_str+1]=url.escape(name).."="..url.escape(value).."&"
|
|
||||||
end
|
|
||||||
return table.concat(get_str)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- generate a charset of characters with ascii codes from 33 to 126
|
-- generate a charset of characters with ascii codes from 33 to 126
|
||||||
-- you can use http://www.asciitable.com/ to see which characters those actually are
|
-- you can use http://www.asciitable.com/ to see which characters those actually are
|
||||||
local charset = generate_charset(33,126)
|
local charset = generate_charset(33,126)
|
||||||
@@ -156,7 +148,7 @@ local function fuzz_form(form, minlen, maxlen, host, port, path)
|
|||||||
if form["method"]=="post" then
|
if form["method"]=="post" then
|
||||||
sending_function = function(data) return http.post(host, port, form_submission_path, nil, nil, data) end
|
sending_function = function(data) return http.post(host, port, form_submission_path, nil, nil, data) end
|
||||||
else
|
else
|
||||||
sending_function = function(data) return http.get(host, port, form_submission_path..generate_get_string(data), {no_cache=true, bypass_cache=true}) end
|
sending_function = function(data) return http.get(host, port, form_submission_path.."?"..url.build_query(data), {no_cache=true, bypass_cache=true}) end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,field in ipairs(form["fields"]) do
|
for _,field in ipairs(form["fields"]) do
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ categories = {"discovery", "intrusive"}
|
|||||||
|
|
||||||
portrule = shortport.http
|
portrule = shortport.http
|
||||||
|
|
||||||
|
local redirect_canary = "http://scanme.nmap.org/"
|
||||||
|
|
||||||
local function dbg(str,...)
|
local function dbg(str,...)
|
||||||
stdnse.debug2(str, ...)
|
stdnse.debug2(str, ...)
|
||||||
end
|
end
|
||||||
@@ -74,10 +76,9 @@ local function checkLocationEcho(query, destination)
|
|||||||
local q = url.parse_query(query);
|
local q = url.parse_query(query);
|
||||||
-- Check the values (and keys) and see if they are reflected in the location header
|
-- Check the values (and keys) and see if they are reflected in the location header
|
||||||
for k,v in pairs(q) do
|
for k,v in pairs(q) do
|
||||||
local s,f = string.find(destination, v)
|
if destination:sub(1, #v) == v then
|
||||||
if s == 1 then
|
|
||||||
-- Build a new URL
|
-- Build a new URL
|
||||||
q[k] = "http%3A%2f%2fscanme.nmap.org%2f";
|
q[k] = redirect_canary;
|
||||||
return url.build_query(q)
|
return url.build_query(q)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -123,7 +124,7 @@ action = function(host, port)
|
|||||||
dbg("Checking potential open redirect: %s:%s%s", host,port,url);
|
dbg("Checking potential open redirect: %s:%s%s", host,port,url);
|
||||||
local testResponse = http.get(host, port, url);
|
local testResponse = http.get(host, port, url);
|
||||||
--dbgt(testResponse)
|
--dbgt(testResponse)
|
||||||
if isRedirect(testResponse.status) and testResponse.header.location == "http://scanme.nmap.org/" then
|
if isRedirect(testResponse.status) and testResponse.header.location == redirect_canary then
|
||||||
table.insert(results, ("%s://%s:%s%s"):format(parsed.scheme, host, port,url))
|
table.insert(results, ("%s://%s:%s%s"):format(parsed.scheme, host, port,url))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -69,14 +69,6 @@ local function generate_safe_postdata(form)
|
|||||||
return postdata
|
return postdata
|
||||||
end
|
end
|
||||||
|
|
||||||
local function generate_get_string(data)
|
|
||||||
local get_str = {"?"}
|
|
||||||
for name,value in pairs(data) do
|
|
||||||
get_str[#get_str+1]=url.escape(name).."="..url.escape(value).."&"
|
|
||||||
end
|
|
||||||
return table.concat(get_str)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- checks each field of a form to see if it's vulnerable to rfi
|
-- checks each field of a form to see if it's vulnerable to rfi
|
||||||
local function check_form(form, host, port, path)
|
local function check_form(form, host, port, path)
|
||||||
local vulnerable_fields = {}
|
local vulnerable_fields = {}
|
||||||
@@ -96,7 +88,7 @@ local function check_form(form, host, port, path)
|
|||||||
if form["method"]=="post" then
|
if form["method"]=="post" then
|
||||||
sending_function = function(data) return http.post(host, port, form_submission_path, nil, nil, data) end
|
sending_function = function(data) return http.post(host, port, form_submission_path, nil, nil, data) end
|
||||||
else
|
else
|
||||||
sending_function = function(data) return http.get(host, port, form_submission_path..generate_get_string(data), nil) end
|
sending_function = function(data) return http.get(host, port, form_submission_path.."?"..url.build_query(data), nil) end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,field in ipairs(form["fields"]) do
|
for _,field in ipairs(form["fields"]) do
|
||||||
@@ -208,7 +200,7 @@ function action(host, port)
|
|||||||
end --for
|
end --for
|
||||||
end --if
|
end --if
|
||||||
|
|
||||||
-- now try inclusion by parameters
|
-- now try inclusion by query parameters
|
||||||
local injectable = {}
|
local injectable = {}
|
||||||
-- search for injectable links (as in sql-injection.nse)
|
-- search for injectable links (as in sql-injection.nse)
|
||||||
if r.response.status and r.response.body then
|
if r.response.status and r.response.body then
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ local function build_injection_vector(urls)
|
|||||||
|
|
||||||
for k, v in pairs(qtab) do
|
for k, v in pairs(qtab) do
|
||||||
old_qtab = qtab[k];
|
old_qtab = qtab[k];
|
||||||
qtab[k] = qtab[k] .. "'%20OR%20sqlspider"
|
qtab[k] = qtab[k] .. "' OR sqlspider"
|
||||||
|
|
||||||
utab.query = url.build_query(qtab)
|
utab.query = url.build_query(qtab)
|
||||||
urlstr = url.build(utab)
|
urlstr = url.build(utab)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ local function getReflected(parsed, r)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function addPayload(v)
|
local function addPayload(v)
|
||||||
return v.."ghz%3Ehzx%22zxc%27xcv"
|
return v.."ghz>hzx\"zxc'xcv"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function createMinedLinks(reflected_values, all_values)
|
local function createMinedLinks(reflected_values, all_values)
|
||||||
|
|||||||
Reference in New Issue
Block a user