161 lines
5.8 KiB
Lua
161 lines
5.8 KiB
Lua
-- better_response.lua
|
|
--
|
|
-- Adds realistic-looking, but fake content to responses based on the type of the request being
|
|
-- made by the bots. This is a demo implementation to demonstrate how scripting works for Eris.
|
|
|
|
-- Random honeytoken generation
|
|
function generate_honeytoken(token)
|
|
local token_types = {
|
|
"API_KEY", "AUTH_TOKEN", "SESSION_ID", "SECRET_KEY",
|
|
"DB_PASSWORD", "ADMIN_TOKEN", "SSH_KEY"
|
|
}
|
|
|
|
local prefix = token_types[math.random(#token_types)]
|
|
local suffix = string.format("%08x%08x", math.random(0xffffffff), math.random(0xffffffff))
|
|
|
|
return prefix .. "_" .. token .. "_" .. suffix
|
|
end
|
|
|
|
-- Generates a "believable" (but fake) error stack trace
|
|
function generate_stack_trace()
|
|
local files = {
|
|
"/var/www/html/index.php",
|
|
"/var/www/html/wp-content/plugins/contact-form-7/includes/submission.php",
|
|
"/var/www/vendor/symfony/http-kernel/HttpKernel.php",
|
|
"/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
|
|
"/var/www/html/app/Controllers/AdminController.php"
|
|
}
|
|
|
|
local functions = {
|
|
"execute", "handle", "processRequest", "loadModel",
|
|
"authenticate", "validateInput", "renderTemplate"
|
|
}
|
|
|
|
local trace = {}
|
|
local depth = math.random(3, 8)
|
|
|
|
for i=1,depth do
|
|
local file = files[math.random(#files)]
|
|
local func = functions[math.random(#functions)]
|
|
local line = math.random(10, 400)
|
|
|
|
table.insert(trace, string.format("#%d %s(%d): %s()", i, file, line, func))
|
|
end
|
|
|
|
return table.concat(trace, "\n")
|
|
end
|
|
|
|
-- Table of response enhancements by type
|
|
local enhancers = {}
|
|
|
|
enhancers.php_exploit = function(text, path, token)
|
|
local honeytoken = generate_honeytoken(token)
|
|
local stack = generate_stack_trace()
|
|
|
|
-- HTML comments that look like sensitive data
|
|
local enhancements = {
|
|
string.format("<!-- DEBUG MODE ENABLED - %s -->", honeytoken),
|
|
string.format("<input type='hidden' name='csrf_token' value='%s'>", honeytoken),
|
|
string.format("<div class='debug-output' style='display:none'>%s</div>", stack),
|
|
string.format("<!-- DB_HOST=localhost DB_USER=webapp_%s DB_PASS=Secret_%s! -->",
|
|
string.sub(token, 1, 8), string.sub(token, -6)),
|
|
"<script>console.log('Failed to load security module. Contact administrator.')</script>"
|
|
}
|
|
|
|
-- Insert appealing content at random positions in the text
|
|
local result = text
|
|
for _, enhancement in ipairs(enhancements) do
|
|
local pos = math.random(1, #result)
|
|
result = string.sub(result, 1, pos) .. enhancement .. string.sub(result, pos+1)
|
|
}
|
|
|
|
return result
|
|
end
|
|
|
|
enhancers.wordpress = function(text, path, token)
|
|
local honeytoken = generate_honeytoken(token)
|
|
|
|
local enhancements = {
|
|
string.format("<meta name='generator' content='WordPress 5.9.6; host=%s'>", token),
|
|
string.format("<!-- WP DEBUG: [Error] Failed to verify nonce '%s' -->", honeytoken),
|
|
string.format("<script>var ajaxurl = 'https://example.com/wp-admin/admin-ajax.php'; var wpApiSettings = {nonce: '%s'}</script>", honeytoken),
|
|
"<!-- Debugging: Failed to load plugin 'security-master' -->",
|
|
string.format("<!-- wpdb error: Table 'wp_%s.wp_users' doesn't exist -->", string.sub(token, 1, 8))
|
|
}
|
|
|
|
local result = text
|
|
for _, enhancement in ipairs(enhancements) do
|
|
local pos = math.random(1, #result)
|
|
result = string.sub(result, 1, pos) .. enhancement .. string.sub(result, pos+1)
|
|
}
|
|
|
|
return result
|
|
end
|
|
|
|
enhancers.api = function(text, path, token)
|
|
-- Create fake API responses that look like they contain tokens or keys
|
|
local api_response = {
|
|
status = "error",
|
|
error = "Authentication required",
|
|
request_id = string.format("req_%s", token),
|
|
debug_token = generate_honeytoken(token),
|
|
_links = {
|
|
documentation = "https://api.example.com/docs",
|
|
support = "https://example.com/api-support"
|
|
}
|
|
}
|
|
|
|
-- Convert to JSON-like string
|
|
local function to_json(obj, indent)
|
|
indent = indent or ""
|
|
local json_str = "{\n"
|
|
|
|
for k, v in pairs(obj) do
|
|
json_str = json_str .. indent .. " \"" .. k .. "\": "
|
|
|
|
if type(v) == "table" then
|
|
json_str = json_str .. to_json(v, indent .. " ")
|
|
elseif type(v) == "string" then
|
|
json_str = json_str .. "\"" .. v .. "\""
|
|
elseif type(v) == "number" then
|
|
json_str = json_str .. tostring(v)
|
|
elseif type(v) == "boolean" then
|
|
json_str = json_str .. tostring(v)
|
|
else
|
|
json_str = json_str .. "null"
|
|
end
|
|
|
|
json_str = json_str .. ",\n"
|
|
end
|
|
|
|
-- Remove trailing comma
|
|
json_str = string.sub(json_str, 1, -3) .. "\n" .. indent .. "}"
|
|
return json_str
|
|
end
|
|
|
|
return text .. "\n<pre class='api-response'>" .. to_json(api_response) .. "</pre>"
|
|
end
|
|
|
|
enhancers.generic = function(text, path, token)
|
|
-- General honeypot enhancements for any path
|
|
local server_info = {
|
|
"Server running Apache/2.4.41",
|
|
"PHP version: 7.4.3",
|
|
string.format("Generated for client: %s", token),
|
|
string.format("Server ID: srv-%s", string.sub(token, 1, 12)),
|
|
string.format("Request processed by worker-%s", string.sub(token, -8))
|
|
}
|
|
|
|
local result = text
|
|
result = result .. "\n<!-- " .. table.concat(server_info, ", ") .. " -->"
|
|
result = result .. string.format("\n<script>console.log('Session tracking enabled: %s')</script>", token)
|
|
|
|
return result
|
|
end
|
|
|
|
-- Main entry point function that Rust will call
|
|
function enhance_response(text, response_type, path, token)
|
|
-- Default to generic if type not found
|
|
local enhancer = enhancers[response_type] or enhancers.generic
|
|
return enhancer(text, path, token)
|
|
end
|