1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-26 17:39:03 +00:00

Fix to the parsing of the --script-args switch [1].

Previously, the --script-args switch would only accept values
with alphanumeric characters or underscores. A full treatise
of the history of changes to this switch and problems can be
found here [2].

Here are the new rules for --script-args definitively:

--script-args <string>

<string> may contain a sequence of key=value pairs and array entries
separated by commas. All whitespace except where noted below is
ignored.

A key, value, or array value may be a sequence of characters except
'{', '}', ',', '=', and all space characters. You may overcome this
restriction by using quotes (single or double) to allow all characters
within the quotation marks. You may also use the quote delimiter
inside the sequence so long as it is escaped by a backslash.

A value for a key/value pair or an array value are allowed to be
a nested table delimited by '{' and '}'.

[1] http://seclists.org/nmap-dev/2009/q2/0204.html
[2] http://seclists.org/nmap-dev/2009/q2/0211.html
This commit is contained in:
batrick
2009-05-29 00:30:56 +00:00
parent fe069f1420
commit 6f51d7d6a9

View File

@@ -54,11 +54,12 @@ local yield = coroutine.yield;
local traceback = debug.traceback;
local byte = string.byte;
local format = string.format;
local find = string.find;
local format = string.format;
local gsub = string.gsub;
local lower = string.lower;
local match = string.match;
local sub = string.sub;
local insert = table.insert;
local remove = table.remove;
@@ -490,14 +491,67 @@ local function run (threads)
progress "endTask";
end
do -- Load script arguments
local args = gsub((cnse.scriptargs or ""), "=([%w_]+)", "=\"%1\"");
local argsf, err = loadstring("return {"..args.."}", "Script Arguments");
if not argsf then
error("failed to parse --script-args:\n"..args.."\n"..err);
else
nmap.registry.args = argsf();
do -- Load script arguments (--script-args)
local args = cnse.scriptargs or "";
-- Parse a string in 'str' at 'start'.
local function parse_string (str, start)
-- Unquoted
local uqi, uqj, uqm = find(str,
"^%s*([^'\"%s{},=][^%s{},=]*)%s*[},=]", start);
-- Quoted
local qi, qj, q, qm = find(str, "^%s*(['\"])(.-[^\\])%1%s*[},=]", start);
-- Empty Quote
local eqi, eqj = find(str, "^%s*(['\"])%1%s*[},=]", start);
if uqi then
return uqm, uqj-1;
elseif qi then
return gsub(qm, "\\"..q, q), qj-1;
elseif eqi then
return "", eqj-1;
else
error("Value around '"..sub(str, start, start+10)..
"' is invalid or is unterminated by a valid seperator");
end
end
-- Takes 'str' at index 'start' and parses a table.
-- Returns the table and the place in the string it finished reading.
local function parse_table (str, start)
local _, j = find(str, "^%s*{", start);
local t = {}; -- table we return
local tmp, nc; -- temporary and next character inspected
while true do
j = j+1; -- move past last token
_, j, nc = find(str, "^%s*(%S)", j);
if nc == "}" then -- end of table
return t, j;
else -- try to read key/value pair, or array value
local av = false; -- this is an array value?
if nc == "{" then -- array value
av, tmp, j = true, parse_table(str, j);
else
tmp, j = parse_string(str, j);
end
nc = sub(str, j+1, j+1); -- next token
if not av and nc == "=" then -- key/value?
_, j, nc = find(str, "^%s*(%S)", j+2);
if nc == "{" then
t[tmp], j = parse_table(str, j);
else -- regular string
t[tmp], j = parse_string(str, j);
end
nc = sub(str, j+1, j+1); -- next token
else -- not key/value pair, save array value
t[#t+1] = tmp;
end
if nc == "," then j = j+1 end -- skip "," token
end
end
end
nmap.registry.args = parse_table("{"..args.."}", 1);
end
-- Load all user chosen scripts