extensions/sandbox_test/try_exploit.lua: Try calling found functions
parent
0e7c9fc6e4
commit
b23711f066
|
@ -48,21 +48,36 @@ local bad_values = {
|
|||
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 = {
|
||||
"meta",
|
||||
"class_meta",
|
||||
"CreateChild",
|
||||
"root",
|
||||
"text",
|
||||
"x",
|
||||
}
|
||||
for _, v in ipairs(bad_names) do -- All bad names are interesting
|
||||
table.insert(interesting_field_names, v)
|
||||
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 = {}
|
||||
for _, v in ipairs(bad_names) do bad_names_set[v] = true end
|
||||
local bad_values_set = {}
|
||||
for _, v in ipairs(bad_values) do bad_values_set[v] = true end
|
||||
local interesting_field_names_set = {}
|
||||
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 result = ""
|
||||
|
@ -114,12 +129,15 @@ local function search(value, checked_values_set, result_list, current_path)
|
|||
table.remove(current_path)
|
||||
end
|
||||
end
|
||||
pcall(f)
|
||||
pcall(f) -- Ignore errors
|
||||
end
|
||||
-- Iterate through the value
|
||||
if type(value) == 'table' then
|
||||
-- Iterate using __next
|
||||
if getmetatable(value) and getmetatable(value).__next then
|
||||
-- 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
|
||||
table.insert(current_path, field_name)
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Iterate through raw table value
|
||||
if type(value) == 'table' then
|
||||
-- Don't use meta.__next
|
||||
local rawpairs = function(t)
|
||||
return next, t, nil
|
||||
|
@ -146,6 +167,26 @@ local function search(value, checked_values_set, result_list, current_path)
|
|||
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
|
||||
|
||||
function M.run()
|
||||
|
@ -204,8 +245,12 @@ function M.run()
|
|||
for _, extname in ipairs(extnames) do
|
||||
try_require_extension(extname)
|
||||
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)
|
||||
new_sandbox.env = local_getfenv(1)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue