extensions/sandbox_test/try_exploit.lua: Try calling found functions

This commit is contained in:
Perttu Ahola 2014-09-28 14:00:17 +03:00
parent 0e7c9fc6e4
commit b23711f066

View File

@ -48,21 +48,36 @@ local bad_values = {
io.popen, io.popen,
} }
-- Have a list of field names to check in case of metatables -- Have a list of field names to check in case of disabled iteration
local interesting_field_names = { local interesting_field_names = {
"meta", "meta",
"class_meta", "class_meta",
"CreateChild",
"root",
"text",
"x",
} }
for _, v in ipairs(bad_names) do -- All bad names are interesting for _, v in ipairs(bad_names) do -- All bad names are interesting
table.insert(interesting_field_names, v) table.insert(interesting_field_names, v)
end end
-- Functions that are known to shutdown the whole application if called without
-- parameters
local function_blacklist = {
"run_script_file",
"send_packet",
"disconnect",
"sub_tick",
}
local bad_names_set = {} local bad_names_set = {}
for _, v in ipairs(bad_names) do bad_names_set[v] = true end for _, v in ipairs(bad_names) do bad_names_set[v] = true end
local bad_values_set = {} local bad_values_set = {}
for _, v in ipairs(bad_values) do bad_values_set[v] = true end for _, v in ipairs(bad_values) do bad_values_set[v] = true end
local interesting_field_names_set = {} local interesting_field_names_set = {}
for _, v in ipairs(interesting_field_names) do interesting_field_names_set[v] = true end for _, v in ipairs(interesting_field_names) do interesting_field_names_set[v] = true end
local function_blacklist_set = {}
for _, v in ipairs(function_blacklist) do function_blacklist_set[v] = true end
local function path_str(path) local function path_str(path)
local result = "" local result = ""
@ -114,12 +129,15 @@ local function search(value, checked_values_set, result_list, current_path)
table.remove(current_path) table.remove(current_path)
end end
end end
pcall(f) pcall(f) -- Ignore errors
end end
-- Iterate through the value -- Iterate using __next
if type(value) == 'table' then if getmetatable(value) and getmetatable(value).__next then
-- Use meta.__next -- Use meta.__next
for field_name, v in pairs(value) do local metapairs = function(t)
return getmetatable(value).__next, t, nil
end
for field_name, v in metapairs(value) do
if v ~= nil then if v ~= nil then
table.insert(current_path, field_name) table.insert(current_path, field_name)
if bad_names_set[field_name] then if bad_names_set[field_name] then
@ -130,6 +148,9 @@ local function search(value, checked_values_set, result_list, current_path)
table.remove(current_path) table.remove(current_path)
end end
end end
end
-- Iterate through raw table value
if type(value) == 'table' then
-- Don't use meta.__next -- Don't use meta.__next
local rawpairs = function(t) local rawpairs = function(t)
return next, t, nil return next, t, nil
@ -146,6 +167,26 @@ local function search(value, checked_values_set, result_list, current_path)
end end
end end
end end
-- If it's a function or callable, call it and check the results
if type(value) == 'function' or
(getmetatable(value) and getmetatable(value).__call) then
-- Don't call if blacklisted
if not function_blacklist_set[current_path[#current_path]] then
-- Call with itself as parameter; that should give the most bang for
-- the buck
log:verbose("search: "..path_str(current_path).."(self)")
function f()
local ret = {value(value)}
for i = 1, table.getn(ret) do
local ret_v = ret[i]
table.insert(current_path, "()["..i.."]")
search(ret_v, checked_values_set, result_list, current_path)
table.remove(current_path)
end
end
pcall(f) -- Ignore errors
end
end
end end
function M.run() function M.run()
@ -204,8 +245,12 @@ function M.run()
for _, extname in ipairs(extnames) do for _, extname in ipairs(extnames) do
try_require_extension(extname) try_require_extension(extname)
end end
-- Make this global so it stays in the environment for checking through
sandbox.make_global({loaded_extensions = loaded_extensions}) -- Make results global so they stay in the environment for checking
sandbox.make_global({
loaded_extensions = loaded_extensions,
})
-- Get the environment (which isn't available for iteration normally) -- Get the environment (which isn't available for iteration normally)
new_sandbox.env = local_getfenv(1) new_sandbox.env = local_getfenv(1)
end end