add module osquery_linux v1.0.0

This commit is contained in:
Roman
2023-01-09 19:56:16 +03:00
parent a943faf956
commit 5aab1e119f
28 changed files with 2135 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
version: "3"
services:
tests:
tty: true
entrypoint:
bash -c "cd soldr-modules && ./tests_framework/lua/bin/busted.linux64.cmd tests/."
build:
context: .
dockerfile: tests/Dockerfile
volumes:
- .:/soldr-modules
# command: tail -f /dev/null
+35
View File
@@ -0,0 +1,35 @@
<template>
<div>
<el-tabs tab-position="left" v-model="leftTab">
<el-tab-pane name="events" :label="$t('BrowserModule.Page.TabTitle.Events')">
<component
:is="components['eventsTable']"
:view-mode="viewMode"
:module-name="module.info.name"
:agent-events="eventsAPI"
:agent-modules="modulesAPI"
></component>
</el-tab-pane>
<el-tab-pane name="config" :label="$t('BrowserModule.Page.TabTitle.Config')">
<component
:is="components['agentModuleConfig']"
:view-mode="viewMode"
:module="module"
:hash="hash"
></component>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
const name = "empty";
module.exports = {
name,
props: ["protoAPI", "hash", "module", "eventsAPI", "modulesAPI", "components", "viewMode"],
data: () => ({
leftTab: "events"
})
};
</script>
+3
View File
@@ -0,0 +1,3 @@
{
"debug": ["true"]
}
+226
View File
@@ -0,0 +1,226 @@
require("system")
require("engine")
local fs = require("fs")
local cjson = require("cjson.safe")
-- variables to initialize event and action engines
local prefix_db = __gid .. "."
local fields_schema = __config.get_fields_schema()
local current_event_config = __config.get_current_event_config()
local module_info = __config.get_module_info()
-- event and action engines initialization
local action_engine = CActionEngine(
{},
__args["debug"][1] == "true"
)
local event_engine = CEventEngine(
fields_schema,
current_event_config,
module_info,
prefix_db,
__args["debug"][1] == "true"
)
local function exec_cmd(cmd, raw)
__log.debugf("cmd to exec: %s", tostring(cmd))
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
__log.debugf("cmd output: %s", tostring(s))
if raw or raw == nil then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end
local module_config = cjson.decode(__config.get_current_config())
local function reread_module_info()
module_config = cjson.decode(__config.get_current_config())
end
local function get_opt_cfg__osquery_config()
return module_config["osquery_config"]
end
local function get_opt_cfg__replace_current_osquery_config()
return module_config["replace_current_osquery_config"]
end
-- return string with raw content of file (use if agent run with admin permissions)
local function get_file_content(path)
local content = ''
local file = io.open(path, "r")
if file then
content = file:read("*a")
file:close()
end
return content
end
-- events executor by event name and data
local function push_event(event_name, event_data)
assert(type(event_name) == "string", "event_name must be a string")
assert(type(event_data) == "table", "event_data must be a table")
-- push the event to the engine
local info = {
["name"] = event_name,
["data"] = event_data,
["actions"] = {},
}
local result, list = event_engine:push_event(info)
-- check result return variable as marker is there need to execute actions
if result then
local data = action_engine:exec(__aid, list)
for action_id, action_result in ipairs(data) do
__log.debugf("action '%s' was requested: '%s'", action_id, action_result)
end
end
end
local function push_event__osquery_already_installed(event_data)
return push_event("osquery_linux_already_installed", event_data)
end
local function push_event__osquery_already_started(event_data)
return push_event("osquery_linux_already_started", event_data)
end
local function push_event__osquery_config_updated_error(event_data)
return push_event("osquery_linux_config_updated_error", event_data)
end
local function push_event__osquery_config_updated_success(event_data)
return push_event("osquery_linux_config_updated_success", event_data)
end
local function push_event__osquery_installed_error(event_data)
return push_event("osquery_linux_installed_error", event_data)
end
local function push_event__osquery_installed_success(event_data)
return push_event("osquery_linux_installed_success", event_data)
end
local function push_event__osquery_started_error(event_data)
return push_event("osquery_linux_started_error", event_data)
end
local function push_event__osquery_started_success(event_data)
return push_event("osquery_linux_started_success", event_data)
end
local function push_event__osquery_unexpected_stopped(event_data)
return push_event("osquery_linux_unexpected_stopped", event_data)
end
local function push_event__osquery_unexpected_uninstalled(event_data)
return push_event("osquery_linux_unexpected_uninstalled", event_data)
end
local function push_event__osquery_uninstalled_error(event_data)
return push_event("osquery_linux_uninstalled_error", event_data)
end
local function push_event__osquery_uninstalled_success(event_data)
return push_event("osquery_linux_uninstalled_success", event_data)
end
-- arguments:
-- * path - path to removed dir
-- return bool
local function is_file_exist(path)
local isfile = fs.is(path, 'file')
return isfile
end
-- return true or false
local function create_file(path)
local f, err, errcode = fs.open(path, 'w+')
if not f then
__log.errorf("error creating file (errcode %s) %s: %s", errcode, path, err)
return false
end
f:close()
return true
end
-- return 'deb' or 'rpm' or ''
local function detect_package_manager()
local cmd = "which dpkg"
local out = exec_cmd(cmd)
__log.debugf("out of cmd '%s': %s", cmd, out)
if out ~= "" then
return "deb"
end
local cmd = "which rpm"
local out = exec_cmd(cmd)
__log.debugf("out of cmd '%s': %s", cmd, out)
if out ~= "" then
return "rpm"
end
return ""
end
local package_manager = detect_package_manager()
local function data_osquery_pkg_path()
local osquery_pkg_prefix = "osquery."
return tostring(__tmpdir) .. "/data/binaries/" .. package_manager .. '/' .. osquery_pkg_prefix .. package_manager
end
-- TODO: remake for package manager
local function get_provided_version_osquery()
local cmd = "dpkg -f " .. data_osquery_pkg_path() .. " version"
if package_manager == 'rpm' then
cmd = 'rpm -qip ' .. data_osquery_pkg_path()
end
local out = exec_cmd(cmd)
__log.debugf("out of cmd '%s': %s", cmd, out)
local result = out:match("%d+.%d+.%d+") or ""
if result == "" then __log.warnf("provided version osquery: %s", result) end
return result
end
return {
exec_cmd = exec_cmd,
get_opt_cfg__osquery_config = get_opt_cfg__osquery_config,
get_opt_cfg__replace_current_osquery_config = get_opt_cfg__replace_current_osquery_config,
push_event__osquery_already_installed = push_event__osquery_already_installed,
push_event__osquery_already_started = push_event__osquery_already_started,
push_event__osquery_config_updated_error = push_event__osquery_config_updated_error,
push_event__osquery_config_updated_success = push_event__osquery_config_updated_success,
push_event__osquery_installed_error = push_event__osquery_installed_error,
push_event__osquery_installed_success = push_event__osquery_installed_success,
push_event__osquery_started_error = push_event__osquery_started_error,
push_event__osquery_started_success = push_event__osquery_started_success,
push_event__osquery_unexpected_stopped = push_event__osquery_unexpected_stopped,
push_event__osquery_unexpected_uninstalled = push_event__osquery_unexpected_uninstalled,
push_event__osquery_uninstalled_error = push_event__osquery_uninstalled_error,
push_event__osquery_uninstalled_success = push_event__osquery_uninstalled_success,
create_file = create_file,
get_file_content = get_file_content,
is_file_exist = is_file_exist,
reread_module_info = reread_module_info,
package_manager = package_manager,
data_osquery_pkg_path = data_osquery_pkg_path,
get_provided_version_osquery = get_provided_version_osquery,
}
+298
View File
@@ -0,0 +1,298 @@
require("engine")
require("system")
local osquery = require("osquery")
local helpers = require("helpers")
__log.debugf("path to temp dir '%s'", __tmpdir)
-- return bool
local function need_to_update_config()
return helpers.get_opt_cfg__replace_current_osquery_config() and
helpers.get_opt_cfg__osquery_config() ~= osquery:get_config()
end
-- ########## PHASES ##########
-- return 'install'/'configure'/'controll'
local function preparing_phase()
if not osquery:is_installed() or not osquery:is_version_correct() then return 'install' end
if osquery:state() ~= "running" and not osquery:start() then
helpers.push_event__osquery_installed_error({
reason = "osquery is already installed but can not start",
version = osquery:get_version(),
})
return "control"
end
helpers.push_event__osquery_already_installed({
reason = "service osqueryd has already installed",
version = osquery:get_version(),
})
if need_to_update_config() then return 'configure' end
return "control"
end
-- installed osquery, check it and push all events
-- return 'configure'/'control'
local function install_phase()
__log.debug("call install_phase")
local success, reason = osquery:install()
if success then
local state = osquery:state()
if state ~= "running" and not osquery:start() then
__log.info("osquery was not installed")
helpers.push_event__osquery_installed_error({
reason = "osquery was installed but can not start",
version = osquery:get_version(),
})
return "control"
end
__log.info("osquery was installed success")
helpers.push_event__osquery_installed_success({
version = osquery:get_version(),
reason = "",
})
if need_to_update_config() then return 'configure' end
return 'control'
end
__log.info("osquery was not installed")
helpers.push_event__osquery_installed_error({
version = helpers.get_provided_version_osquery(),
reason = reason,
})
return 'control'
end
-- update osquery config
-- return 'control'
local function configure_phase()
__log.debug("call configure_phase")
local replace_current_osquery_config = helpers.get_opt_cfg__replace_current_osquery_config()
if not replace_current_osquery_config then
__log.debug("skip configure phase, replace_current_osquery_config: %s", replace_current_osquery_config)
return 'control'
end
local version = osquery:get_version()
local config_path = osquery:get_config_path()
if config_path == '' then
local err = "failed to update osquery config file, can't find or create config path"
__log.error(err)
helpers.push_event__osquery_config_updated_error({
reason = err,
version = version,
})
return "control"
end
if not osquery:update_config_file() then
local err = "failed to update config file to module directory"
__log.error(err)
helpers.push_event__osquery_config_updated_error({
reason = err,
version = version,
})
return "control"
end
if not osquery:stop() then
local err = "can not restart osquery after update config (can not stop osquery)"
__log.error(err)
helpers.push_event__osquery_config_updated_error({
reason = err,
version = version,
})
return "control"
end
if not osquery:start() then
local err = "can not restart osquery after update config (can not start osquery)"
__log.error(err)
helpers.push_event__osquery_config_updated_error({
reason = err,
version = version,
})
return "control"
end
__log.info("osquery config updated success")
helpers.push_event__osquery_config_updated_success({
version = version,
})
return "control"
end
-- return 'install' or nothing
local function control_phase()
local last_state = osquery:state()
local version = helpers.get_provided_version_osquery()
if last_state == "running" then
version = osquery:get_version()
end
local change_state
while not __api.is_close() do
local current_state = osquery:state()
if last_state == current_state then goto continue end
change_state = "from: " .. last_state .. ", to: " .. current_state
if current_state == "unknown" then
__log.warnf("osquery was unexpected uninstalled (state: %s)", change_state)
helpers.push_event__osquery_unexpected_uninstalled({
version = version,
reason = change_state,
})
return "install"
end
if current_state == "stopped" then
__log.warnf("osquery was unexpected stopped (state: %s)", change_state)
__log.info("osquery is stopped and should be running")
helpers.push_event__osquery_unexpected_stopped({
reason = change_state,
version = version,
})
if not osquery:start() then
local err = "failed to start osquery, change state: " .. change_state
__log.error(err)
helpers.push_event__osquery_started_error({
reason = err,
version = version,
})
last_state = "stopped"
goto continue
end
version = osquery:get_version()
__log.infof("osquery %s started success, change state: %s", version, change_state)
helpers.push_event__osquery_started_success({
reason = change_state,
version = version,
})
last_state = "running"
goto continue
end
if current_state == "running" then
version = osquery:get_version()
helpers.push_event__osquery_already_started({
reason = change_state,
version = version,
})
last_state = "running"
end
::continue::
__api.await(10000)
end
end
-- ########## SYSTEM FUNCTIONS AND CALLBACKS ##########
-- set default timeout to wait exit on blocking of recv_* functions
__api.set_recv_timeout(5000) -- 5s
__api.add_cbs({
-- data = function(src, data)
-- file = function(src, path, name)
-- text = function(src, text, name)
-- msg = function(src, msg, mtype)
-- action = function(src, data, name)
control = function(cmtype, data)
__log.infof("receive control msg '%s' with payload: %s", cmtype, data)
if cmtype == 'update_config' then
helpers.reread_module_info()
configure_phase()
return true
end
if cmtype == 'quit' then
if not osquery:is_installed() then
__log.info("quit from module without uninstalation osquery")
return true
end
local version = osquery:get_version()
local success, reason = osquery:uninstall()
if success then
__log.info("osquery was uninstalled success")
helpers.push_event__osquery_uninstalled_success({
version = version,
})
return true
end
__log.errorf("osquery was not uninstalled, reason: %s", reason)
helpers.push_event__osquery_uninstalled_error({
version = version,
reason = reason,
})
end
return true
end,
})
__log.infof("module '%s' was started", __config.ctx.name)
local next_phase = preparing_phase()
while next_phase do
__log.debugf("the next phase '%s'", next_phase)
if next_phase == "install" then
next_phase = install_phase()
elseif next_phase == "configure" then
next_phase = configure_phase()
elseif next_phase == "control" then
next_phase = control_phase()
else
__log.errorf("unexpected next handler: %s", next_phase)
break
end
end
__log.infof("module '%s' was stopped", __config.ctx.name)
return 'success'
+166
View File
@@ -0,0 +1,166 @@
require("system")
local helpers = require("helpers")
--local sysinfo = CSystemInfo({})
-- Module immutable global variables
local osquery_config_name = "osquery.conf"
local path_to_dumped_config = tostring(__tmpdir) .. "/" .. osquery_config_name
local Osquery = {}
-- linux
-- return string with path to config of installed osquery
function Osquery:get_config_path()
local path = '/etc/osquery/osquery.conf'
if helpers.is_file_exist(path) or helpers.create_file(path) then return path end
return ''
end
-- linux
-- return bool
function Osquery:is_installed()
return self:get_version() ~= ""
end
-- linux
-- return string like '5.5.1'
function Osquery:get_version()
local cmd = "osqueryd --version"
local out = helpers.exec_cmd(cmd)
__log.debugf("out of cmd '%s': %s", cmd, out)
local result = out:match("%d+.%d+.%d+") or ""
return result
end
-- linux
-- return bool
function Osquery:is_version_correct()
local version = self:get_version()
__log.infof("found osquery version '%s'", version)
return version == helpers.get_provided_version_osquery()
end
-- linux
-- return string contaned raw config by installed osquery
function Osquery:get_config()
local path = self:get_config_path()
if path == '' then return '' end
return helpers.get_file_content(path)
end
-- linux
-- return boolean
function Osquery:update_config_file()
local config_path = self:get_config_path()
local file = io.open(config_path, "w+")
if not file then
return false
end
local _ = file:write(helpers.get_opt_cfg__osquery_config())
file:close()
return self:get_config() == helpers.get_opt_cfg__osquery_config()
end
-- linux
-- returns 2 agrs: bool, string (reason)
function Osquery:install()
local cmd = "dpkg -i " .. helpers.data_osquery_pkg_path()
if helpers.package_manager == 'rpm' then
cmd = 'rpm -i ' .. helpers.data_osquery_pkg_path()
end
local out = helpers.exec_cmd(cmd) or ""
__log.infof("out of cmd '%s': %s", cmd, out)
local success = self:is_installed()
local reason = ""
if not success then reason = "osquery can not installed" end
return success, reason
end
-- linux
-- remove osquery from machine
-- returns
-- * bool: result of uninstalation
-- * string: reason of failed uninstalation
function Osquery:uninstall()
local cmd = 'systemctl stop osqueryd'
local out = helpers.exec_cmd(cmd) or ""
__log.debugf("out of cmd '%s': %s", cmd, out)
cmd = 'dpkg --force-all -P osquery'
if helpers.package_manager == 'rpm' then
cmd = 'rpm -e osquery'
end
out = helpers.exec_cmd(cmd) or ""
__log.debugf("out of cmd '%s': %s", cmd, out)
os.execute("sleep 2")
if not self:is_installed() then return true, "" end
local state = self:state()
return false, "error uninstalation osquery, current state: " .. state
end
-- linux
-- return: string of running, stopped, unknown
function Osquery:state()
if not self:is_installed() then return 'unknown' end
local cmd = 'systemctl is-active osqueryd'
local out = helpers.exec_cmd(cmd) or ''
__log.debugf("out of cmd '%s': %s", cmd, out)
if out == "unknown\n" then return "unknown" end
if out == "active\n" then return "running" end
return "stopped"
end
-- linux
-- return true/false
function Osquery:start()
local cmd = 'systemctl start osqueryd'
local out = helpers.exec_cmd(cmd) or ""
__log.debugf("out of cmd '%s': %s", cmd, out)
local state = self:state()
if state == 'running' then return true end
cmd = 'systemctl enable osqueryd'
out = helpers.exec_cmd(cmd) or ""
__log.debugf("out of cmd '%s': %s", cmd, out)
state = self:state()
if state == 'running' then return true end
return false
end
-- linux
-- return true/false
function Osquery:stop()
local cmd = 'systemctl stop osqueryd'
local out = helpers.exec_cmd(cmd) or ""
__log.debugf("out of cmd '%s': %s", cmd, out)
local state = self:state()
if state ~= 'stopped' then return false end
return true
end
return Osquery
@@ -0,0 +1,6 @@
{
"additionalProperties": false,
"properties": {},
"required": [],
"type": "object"
}
+14
View File
@@ -0,0 +1,14 @@
{
"1.0.0": {
"en": {
"date": "01-09-2023",
"title": "Base functionality",
"description": "Added installation and configure osquery on agent for linux"
},
"ru": {
"date": "09.01.2023",
"title": "Базовая функциональность",
"description": "Добавлена возможность установки и конфигурирования osquery на агенте для ОС linux"
}
}
}
@@ -0,0 +1,31 @@
{
"additionalProperties": false,
"properties": {
"osquery_config": {
"rules": {},
"type": "string",
"ui": {
"widget": "textarea",
"widgetConfig": {
"autoSize": {
"maxRows": 20,
"minRows": 10
},
"rows": 10
}
}
},
"replace_current_osquery_config": {
"rules": {},
"type": "boolean",
"ui": {
"widgetConfig": {}
}
}
},
"required": [
"osquery_config",
"replace_current_osquery_config"
],
"type": "object"
}
@@ -0,0 +1 @@
{}
@@ -0,0 +1,4 @@
{
"osquery_config": "{\n \"options\": {\n \"logger_plugin\": \"windows_event_log\"\n },\n \"schedule\": {\n \"system_info\": {\n \"query\": \"SELECT hostname, cpu_brand, physical_memory FROM system_info;\",\n \"interval\": 3600\n }\n },\n\n \"decorators\": {\n \"load\": [\n \"SELECT uuid AS host_uuid FROM system_info;\",\n \"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;\"\n ]\n },\n\n // Add default osquery packs or install your own.\n //\n // There are several 'default' packs installed via\n // packages and/or Homebrew.\n //\n // Linux: /opt/osquery/share/osquery/packs\n // OS X: /var/osquery/packs\n // Homebrew: /usr/local/share/osquery/packs\n // make install: {PREFIX}/share/osquery/packs\n //\n \"packs\": {\n // \"osquery-monitoring\": \"/opt/osquery/share/osquery/packs/osquery-monitoring.conf\",\n // \"incident-response\": \"/opt/osquery/share/osquery/packs/incident-response.conf\",\n // \"it-compliance\": \"/opt/osquery/share/osquery/packs/it-compliance.conf\",\n // \"osx-attacks\": \"/var/osquery/packs/osx-attacks.conf\",\n // \"vuln-management\": \"/opt/osquery/share/osquery/packs/vuln-management.conf\",\n // \"hardware-monitoring\": \"/opt/osquery/share/osquery/packs/hardware-monitoring.conf\",\n // \"ossec-rootkit\": \"/opt/osquery/share/osquery/packs/ossec-rootkit.conf\",\n // \"windows-hardening\": \"C:\\\\Program Files\\\\osquery\\\\packs\\\\windows-hardening.conf\",\n // \"windows-attacks\": \"C:\\\\Program Files\\\\osquery\\\\packs\\\\windows-attacks.conf\"\n },\n\n // Provides feature vectors for osquery to leverage in simple statistical \n // analysis of results data. \n //\n // Currently this configuration is only used by Windows in the Powershell\n // Events table, wherein character_frequencies is a list of doubles \n // representing the aggregate occurrence of character values in Powershell \n // Scripts. A default configuration is provided which was adapated from \n // Lee Holmes cobbr project: \n // https://gist.github.com/cobbr/acbe5cc7a186726d4e309070187beee6\n // \n \"feature_vectors\": {\n \"character_frequencies\": [\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.00045, 0.01798,\n 0.0, 0.03111, 0.00063, 0.00027, 0.0, 0.01336, 0.0133,\n 0.00128, 0.0027, 0.00655, 0.01932, 0.01917, 0.00432, 0.0045,\n 0.00316, 0.00245, 0.00133, 0.001029, 0.00114, 0.000869, 0.00067,\n 0.000759, 0.00061, 0.00483, 0.0023, 0.00185, 0.01342, 0.00196,\n 0.00035, 0.00092, 0.027875, 0.007465, 0.016265, 0.013995, 0.0490895,\n 0.00848, 0.00771, 0.00737, 0.025615, 0.001725, 0.002265, 0.017875,\n 0.016005, 0.02533, 0.025295, 0.014375, 0.00109, 0.02732, 0.02658,\n 0.037355, 0.011575, 0.00451, 0.005865, 0.003255, 0.005965, 0.00077,\n 0.00621, 0.00222, 0.0062, 0.0, 0.00538, 0.00122, 0.027875,\n 0.007465, 0.016265, 0.013995, 0.0490895, 0.00848, 0.00771, 0.00737,\n 0.025615, 0.001725, 0.002265, 0.017875, 0.016005, 0.02533, 0.025295,\n 0.014375, 0.00109, 0.02732, 0.02658, 0.037355, 0.011575, 0.00451,\n 0.005865, 0.003255, 0.005965, 0.00077, 0.00771, 0.002379, 0.00766,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0\n ]\n } \n}\n",
"replace_current_osquery_config": true
}
@@ -0,0 +1,179 @@
{
"osquery_linux_already_installed": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_already_started": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_config_updated_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_config_updated_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
},
"osquery_linux_installed_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_installed_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
},
"osquery_linux_started_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_started_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_unexpected_stopped": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_unexpected_uninstalled": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_uninstalled_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_uninstalled_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
}
}
@@ -0,0 +1 @@
{}
@@ -0,0 +1,4 @@
{
"osquery_config": "{\n \"options\": {\n \"logger_plugin\": \"windows_event_log\"\n },\n \"schedule\": {\n \"system_info\": {\n \"query\": \"SELECT hostname, cpu_brand, physical_memory FROM system_info;\",\n \"interval\": 3600\n }\n },\n\n \"decorators\": {\n \"load\": [\n \"SELECT uuid AS host_uuid FROM system_info;\",\n \"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;\"\n ]\n },\n\n // Add default osquery packs or install your own.\n //\n // There are several 'default' packs installed via\n // packages and/or Homebrew.\n //\n // Linux: /opt/osquery/share/osquery/packs\n // OS X: /var/osquery/packs\n // Homebrew: /usr/local/share/osquery/packs\n // make install: {PREFIX}/share/osquery/packs\n //\n \"packs\": {\n // \"osquery-monitoring\": \"/opt/osquery/share/osquery/packs/osquery-monitoring.conf\",\n // \"incident-response\": \"/opt/osquery/share/osquery/packs/incident-response.conf\",\n // \"it-compliance\": \"/opt/osquery/share/osquery/packs/it-compliance.conf\",\n // \"osx-attacks\": \"/var/osquery/packs/osx-attacks.conf\",\n // \"vuln-management\": \"/opt/osquery/share/osquery/packs/vuln-management.conf\",\n // \"hardware-monitoring\": \"/opt/osquery/share/osquery/packs/hardware-monitoring.conf\",\n // \"ossec-rootkit\": \"/opt/osquery/share/osquery/packs/ossec-rootkit.conf\",\n // \"windows-hardening\": \"C:\\\\Program Files\\\\osquery\\\\packs\\\\windows-hardening.conf\",\n // \"windows-attacks\": \"C:\\\\Program Files\\\\osquery\\\\packs\\\\windows-attacks.conf\"\n },\n\n // Provides feature vectors for osquery to leverage in simple statistical \n // analysis of results data. \n //\n // Currently this configuration is only used by Windows in the Powershell\n // Events table, wherein character_frequencies is a list of doubles \n // representing the aggregate occurrence of character values in Powershell \n // Scripts. A default configuration is provided which was adapated from \n // Lee Holmes cobbr project: \n // https://gist.github.com/cobbr/acbe5cc7a186726d4e309070187beee6\n // \n \"feature_vectors\": {\n \"character_frequencies\": [\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.00045, 0.01798,\n 0.0, 0.03111, 0.00063, 0.00027, 0.0, 0.01336, 0.0133,\n 0.00128, 0.0027, 0.00655, 0.01932, 0.01917, 0.00432, 0.0045,\n 0.00316, 0.00245, 0.00133, 0.001029, 0.00114, 0.000869, 0.00067,\n 0.000759, 0.00061, 0.00483, 0.0023, 0.00185, 0.01342, 0.00196,\n 0.00035, 0.00092, 0.027875, 0.007465, 0.016265, 0.013995, 0.0490895,\n 0.00848, 0.00771, 0.00737, 0.025615, 0.001725, 0.002265, 0.017875,\n 0.016005, 0.02533, 0.025295, 0.014375, 0.00109, 0.02732, 0.02658,\n 0.037355, 0.011575, 0.00451, 0.005865, 0.003255, 0.005965, 0.00077,\n 0.00621, 0.00222, 0.0062, 0.0, 0.00538, 0.00122, 0.027875,\n 0.007465, 0.016265, 0.013995, 0.0490895, 0.00848, 0.00771, 0.00737,\n 0.025615, 0.001725, 0.002265, 0.017875, 0.016005, 0.02533, 0.025295,\n 0.014375, 0.00109, 0.02732, 0.02658, 0.037355, 0.011575, 0.00451,\n 0.005865, 0.003255, 0.005965, 0.00077, 0.00771, 0.002379, 0.00766,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\n 0.0, 0.0, 0.0\n ]\n } \n}\n",
"replace_current_osquery_config": true
}
@@ -0,0 +1,179 @@
{
"osquery_linux_already_installed": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_already_started": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_config_updated_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_config_updated_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
},
"osquery_linux_installed_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_installed_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
},
"osquery_linux_started_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_started_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_unexpected_stopped": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_unexpected_uninstalled": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_uninstalled_error": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"reason",
"version"
],
"type": "atomic"
},
"osquery_linux_uninstalled_success": {
"actions": [
{
"fields": [],
"module_name": "this",
"name": "log_to_db",
"priority": 10
}
],
"fields": [
"version"
],
"type": "atomic"
}
}
@@ -0,0 +1 @@
[]
@@ -0,0 +1,386 @@
{
"additionalProperties": false,
"properties": {
"osquery_linux_already_installed": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_already_started": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_config_updated_error": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_config_updated_success": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"version"
],
"items": {
"enum": [
"version"
],
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_installed_error": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_installed_success": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"version"
],
"items": {
"enum": [
"version"
],
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_started_error": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_started_success": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_unexpected_stopped": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_unexpected_uninstalled": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_uninstalled_error": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"reason",
"version"
],
"items": {
"enum": [
"reason",
"version"
],
"type": "string"
},
"maxItems": 2,
"minItems": 2,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
},
"osquery_linux_uninstalled_success": {
"allOf": [
{
"$ref": "#/definitions/events.atomic"
},
{
"properties": {
"fields": {
"default": [
"version"
],
"items": {
"enum": [
"version"
],
"type": "string"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
}
},
"required": [
"fields"
],
"type": "object"
}
]
}
},
"required": [
"osquery_linux_already_installed",
"osquery_linux_already_started",
"osquery_linux_config_updated_error",
"osquery_linux_config_updated_success",
"osquery_linux_installed_error",
"osquery_linux_installed_success",
"osquery_linux_started_error",
"osquery_linux_started_success",
"osquery_linux_unexpected_stopped",
"osquery_linux_unexpected_uninstalled",
"osquery_linux_uninstalled_error",
"osquery_linux_uninstalled_success"
],
"type": "object"
}
@@ -0,0 +1,23 @@
{
"additionalProperties": true,
"properties": {
"reason": {
"rules": {},
"type": "string",
"ui": {
"widgetConfig": {}
}
},
"version": {
"rules": {},
"type": "string",
"ui": {
"widgetConfig": {}
}
}
},
"required": [
"version"
],
"type": "object"
}
+38
View File
@@ -0,0 +1,38 @@
{
"name": "osquery_linux",
"template": "empty",
"version": {
"major": 1,
"minor": 0,
"patch": 0
},
"os": {
"linux": [
"386",
"amd64"
]
},
"system": false,
"actions": [],
"events": [
"osquery_linux_already_installed",
"osquery_linux_already_started",
"osquery_linux_config_updated_error",
"osquery_linux_config_updated_success",
"osquery_linux_installed_error",
"osquery_linux_installed_success",
"osquery_linux_started_error",
"osquery_linux_started_success",
"osquery_linux_unexpected_stopped",
"osquery_linux_unexpected_uninstalled",
"osquery_linux_uninstalled_error",
"osquery_linux_uninstalled_success"
],
"fields": [
"reason",
"version"
],
"tags": [
"osquery"
]
}
+206
View File
@@ -0,0 +1,206 @@
{
"module": {
"en": {
"title": "Osquery installer (linux)",
"description": "The module installed and configured osquery application on linux machines"
},
"ru": {
"title": "Установщик osquery (linux)",
"description": "Модуль устанавливает и конфигурирует приложение osquery на устройствах linux"
}
},
"config": {
"osquery_config": {
"en": {
"title": "Osquery config",
"description": ""
},
"ru": {
"title": "Конфигурация osquery",
"description": ""
}
},
"replace_current_osquery_config": {
"en": {
"title": "Is need to replace current osquery config?",
"description": ""
},
"ru": {
"title": "Необходимо заменить текущую конфигурацию osquery?",
"description": ""
}
}
},
"fields": {
"reason": {
"en": {
"title": "reason",
"description": "reason"
},
"ru": {
"title": "Причина",
"description": "reason"
}
},
"version": {
"en": {
"title": "version",
"description": "version"
},
"ru": {
"title": "Версия",
"description": "версия"
}
}
},
"actions": {},
"events": {
"osquery_linux_already_installed": {
"en": {
"title": "The module detected Osquery installed on an agent",
"description": "The module detected Osquery installed in OS:\n{{ reason }}"
},
"ru": {
"title": "Модуль обнаружил установленный Osquery на агенте",
"description": "Модуль обнаружил установленный Osquery в ОС:\n{{ reason }}"
}
},
"osquery_linux_already_started": {
"en": {
"title": "The module detected Osquery already running on an agent",
"description": "The module detected Osquery already running in OS:\n{{ reason }}"
},
"ru": {
"title": "Модуль обнаружил уже запущенный Osquery на агенте",
"description": "Модуль обнаружил уже запущенный Osquery в ОС:\n{{ reason }}"
}
},
"osquery_linux_config_updated_error": {
"en": {
"title": "The module could not update the Osquery configuration on an agent",
"description": "The module could not update the Osquery configuration {{ version }} on an agent:\n{{ reason }}"
},
"ru": {
"title": "Модуль не смог обновить конфигурацию Osquery на агенте",
"description": "Модуль не смог обновить конфигурацию Osquery {{ version }}, причина:\n{{ reason }}"
}
},
"osquery_linux_config_updated_success": {
"en": {
"title": "The module updated the Osquery configuration on an agent",
"description": "The module updated the Osquery configuration '{{ version }}' on an agent"
},
"ru": {
"title": "Модуль обновил конфигурацию Osquery на агенте",
"description": "Модуль обновил конфигурацию Osquery {{ version }} на агенте"
}
},
"osquery_linux_installed_error": {
"en": {
"title": "The module could not install the Osquery on an agent",
"description": "The module could not install the Osquery '{{ version }}' on an agent:\n{{ reason }}"
},
"ru": {
"title": "Модуль не смог установить Osquery на агенте",
"description": "Модуль не смог установить Osquery {{ version }} на агенте, причина:\n{{ reason }}"
}
},
"osquery_linux_installed_success": {
"en": {
"title": "The module installed Osquery on an agent",
"description": "The module installed Osquery '{{ version }}' on an agent"
},
"ru": {
"title": "Модуль установил Osquery на агенте",
"description": "Модуль установил Osquery {{ version }} на агенте"
}
},
"osquery_linux_started_error": {
"en": {
"title": "The module could not start Osquery on an agent",
"description": "The module could not start the Osquery '{{ version }}' on an agent:\n{{ reason }}"
},
"ru": {
"title": "Модуль не смог запустить Osquery на агенте",
"description": "Модуль не смог запустить Osquery {{ version }} на агенте, причина:\n{{ reason }}"
}
},
"osquery_linux_started_success": {
"en": {
"title": "The module started Osquery on an agent",
"description": "The module started Osquery '{{ version }}' on an agent"
},
"ru": {
"title": "Модуль запустил Osquery на агенте",
"description": "Модуль запустил Osquery {{ version }} на агенте"
}
},
"osquery_linux_unexpected_stopped": {
"en": {
"title": "Osquery was stopped on an agent",
"description": "Osquery '{{ version }}' was stopped on an agent:\n{{ reason }}"
},
"ru": {
"title": "Osquery был остановлен на агенте",
"description": "Osquery {{ version }} был остановлен на агенте, причина:\n{{ reason }}"
}
},
"osquery_linux_unexpected_uninstalled": {
"en": {
"title": "Osquery was deleted on an agent",
"description": "Osquery '{{ version }}' was deleted on an agent:\n{{ reason }}"
},
"ru": {
"title": "Osquery был удален на агенте",
"description": "Osquery {{ version }} был удален на агенте, причина:\n{{ reason }}"
}
},
"osquery_linux_uninstalled_error": {
"en": {
"title": "The module could not delete Osquery on an agent",
"description": "The module could not delete the Osquery '{{ version }}' on an agent:\n{{ reason }}"
},
"ru": {
"title": "Модуль не смог удалить Osquery на агенте",
"description": "Модуль не смог удалить Osquery {{ version }} на агенте, причина:\n{{ reason }}"
}
},
"osquery_linux_uninstalled_success": {
"en": {
"title": "The module deleted Osquery on an agent",
"description": "The module deleted Osquery '{{ version }}' on an agent"
},
"ru": {
"title": "Модуль удалил Osquery на агенте",
"description": "Модуль удалил Osquery {{ version }} на агенте"
}
}
},
"action_config": {},
"event_config": {
"osquery_linux_already_installed": {},
"osquery_linux_already_started": {},
"osquery_linux_config_updated_error": {},
"osquery_linux_config_updated_success": {},
"osquery_linux_installed_error": {},
"osquery_linux_installed_success": {},
"osquery_linux_started_error": {},
"osquery_linux_started_success": {},
"osquery_linux_unexpected_stopped": {},
"osquery_linux_unexpected_uninstalled": {},
"osquery_linux_uninstalled_error": {},
"osquery_linux_uninstalled_success": {}
},
"tags": {
"osquery": {
"en": {
"title": "osquery",
"description": "osquery"
},
"ru": {
"title": "osquery",
"description": "osquery"
}
}
}
}
@@ -0,0 +1 @@
[]
+4
View File
@@ -0,0 +1,4 @@
{
"debug": ["true"],
"handshake": ["true"]
}
+161
View File
@@ -0,0 +1,161 @@
require("engine")
local ffi = require'ffi'
local curl = require'libcurl'
local cjson = require "cjson.safe"
local prefix_db = __gid .. "."
local event_data_schema = __config.get_fields_schema()
local current_event_config = __config.get_current_event_config()
local module_info = __config.get_module_info()
local event_engine = CEventEngine(event_data_schema, current_event_config, module_info, prefix_db, true)
local action_engine = CActionEngine({}, true)
-- for overriding debug argument
local g_print = print
local print = function(...)
if __args["debug"][1] == "true" then
g_print(...);
end
end
-- for example ganarate test json document by json schema
local function generate_json(schema)
local result = ""
local function wrire(raw)
result = ffi.string(ffi.cast("char*", raw))
return #result
end
curl.easy{
url = 'https://json.vxcontrol.app/api/v1/schema',
post = 1,
httpheader = {
"Content-Type: application/json",
},
postfields = schema;
writefunction = wrire
}
:perform()
:close()
return cjson.decode(result)
end
-- for example push of test events for ones from current config
local function push_events(id)
local event_config = cjson.decode(__config.get_current_event_config())
for event_name, _ in pairs(event_config or {}) do
local info = { name = event_name, data = generate_json(__config.get_fields_schema()) }
local result, list = event_engine:push_event(info)
if result then
for action_id, action_result in ipairs(action_engine:exec(id, list)) do
print("action " .. tostring(action_id) .. " was executed: ", action_result)
end
end
end
end
-- for debugging used printing initial agent connected list
local function print_agents()
print("__agents:")
for i, a in pairs(__agents.dump()) do
print("\t", i, type(a))
print("\t\t", "ID:", a.ID)
print("\t\t", "IP:", a.IP)
print("\t\t", "Src:", a.Src)
print("\t\t", "Dst:", a.Dst)
print("\t\t", "Type:", a.Type)
print("\t\t", "Info:", type(a.Info))
if a.Info ~= nil then
print("\t\t\t", "Info.Os:", type(a.Info.Os))
if a.Info.Os ~= nil then
print("\t\t\t\t", "Info.Os.Type:", a.Info.Os.Type)
print("\t\t\t\t", "Info.Os.Name:", a.Info.Os.Name)
print("\t\t\t\t", "Info.Os.Arch:", a.Info.Os.Arch)
end
print("\t\t\t", "Info.User:", type(a.Info.User))
if a.Info.User ~= nil then
print("\t\t\t\t", "Info.User.Name:", a.Info.User.Name)
print("\t\t\t\t", "Info.User.Group:", a.Info.User.Group)
end
end
print()
end
print()
end
-- for example getting agent ID by dst token on agent connected event
local function get_agent_id(dst)
for i, a in pairs(__agents.dump()) do
if i == dst then
return a.ID
end
end
return ""
end
-- set default timeout to wait exit on blocking of recv_* functions
__api.set_recv_timeout(5000) -- 5s
__api.add_cbs({
data = function(src, data)
print('receive data: "' .. data .. '" from: ' .. src)
local msg = cjson.decode(data)
if msg['type'] == 'hs_agent' then
local hs_server_msg = cjson.encode({['type'] = 'hs_server', ['data'] = "pong"})
if __args["handshake"][1] == "true" then
__api.await(100)
print("sent hs server msg to ", src, ": ", __api.send_data_to(src, hs_server_msg))
end
else
print("receive unknown type message", msg['type'])
end
print()
return true
end,
file = function(src, path, name)
print('receive file: "' .. path .. '" / "' .. name .. '" from: ' .. src)
return true
end,
text = function(src, text, name)
print('receive text: "' .. text .. '" / "' .. name .. '" from: ' .. src)
return true
end,
msg = function(src, msg, mtype)
print('receive msg: "' .. msg .. '" / "' .. tostring(mtype) .. '" from: ' .. src)
return true
end,
action = function(src, data, name)
print('receive action: "' .. data .. '" / "' .. name .. '" from: ' .. src)
return true
end,
control = function(cmtype, data)
local src = data
print('receive control msg: "' .. cmtype .. '" from: ' .. src)
print_agents()
if cmtype == "agent_connected" then
print("agent_connected")
push_events(get_agent_id(src))
end
if cmtype == "agent_disconnected" then
print("agent_disconnected")
end
return true
end,
})
g_print("module " .. tostring(__api.get_name()) .. " was started")
for _, a in pairs(__agents.dump()) do
push_events(a.ID)
end
__api.await(-1)
g_print("module " .. tostring(__api.get_name()) .. " was stopped")
return 'success'
+12
View File
@@ -0,0 +1,12 @@
FROM ubuntu:20.04
RUN apt update; apt install -y --no-install-recommends systemctl
ENV APP_PATH=/soldr-modules \
LUAPOWER_PLATFORM=linux64
ENV LUA_PATH=$APP_PATH/tests_framework/lua/?.lua;$APP_PATH/tests_framework/lua/?/init.lua;$APP_PATH/luapower/?.lua;$APP_PATH/luapower/?/init.lua;$APP_PATH/utils/?.lua;$APP_PATH/utils/?/init.lua \
LUA_CPATH=$APP_PATH/luapower/bin/$LUAPOWER_PLATFORM/lib?.dylib;$APP_PATH/luapower/bin/$LUAPOWER_PLATFORM/clib/?.so; \
LUA_BIN=$APP_PATH/luapower/bin/$LUAPOWER_PLATFORM/luajit-bin
ENTRYPOINT ["/bin/bash"]
+137
View File
@@ -0,0 +1,137 @@
require 'busted.runner'()
local ffi = require('ffi')
---------------------------------------------------
-- mock helper functions
---------------------------------------------------
local function mock_expect_event(name)
return __mock:expect("event", function(o)
return o.event and o.event.name == name
end)
end
local function mock_get_event_context(name)
return __mock:pop_from_context("event", function(o)
return o.event and o.event.name == name
end)
end
---------------------------------------------------
-- osquery helper functions
---------------------------------------------------
local function osquery_uninstall()
print("uninstallation osquery in test")
io.popen('dpkg --force-all -P osquery 2> /dev/null', 'r')
end
local function osquery_stop()
print("stopping osquery in test")
io.popen('systemctl stop osqueryd', 'r')
end
describe('osquery_linux agent', function()
setup(function()
_G.__mock = {
vars = {},
timeout = 60, -- in seconds
cwd = "tmpcwd",
module = "osquery_linux",
version = "1.0.0",
side = "agent",
log_level = os.getenv("LOG_LEVEL") or "info", -- error, warn, info, debug, trace
}
-- load mocked environment
require("mock")
-- hack, see: https://github.com/vxcontrol/soldr-modules/issues/42
__mock.module_info.fields = { "reason", "version" }
__mock.module_info.actions = {}
__mock.module_info.events = {
"osquery_linux_already_installed",
"osquery_linux_already_started",
"osquery_linux_config_updated_error",
"osquery_linux_config_updated_success",
"osquery_linux_installed_error",
"osquery_linux_installed_success",
"osquery_linux_started_error",
"osquery_linux_started_success",
"osquery_linux_unexpected_stopped",
"osquery_linux_unexpected_uninstalled",
"osquery_linux_uninstalled_error",
"osquery_linux_uninstalled_success"
}
osquery_uninstall()
end)
before_each(function()
__mock:clear_expectations()
end)
teardown(function()
-- stop module actually wait for module coroutine to finish execution
osquery_uninstall()
__mock:module_stop()
end)
context('osquery module life circle', function()
if ffi.os ~= 'Linux' then
describe('installing osquery', function()
it('should not install osquery', function()
--__mock:module_start()
--for i, data in ipairs(__mock.stage.ctx["event"]) do
-- print("i", i)
-- print("data", data)
--end
assert.equal(table.getn(__mock.stage.ctx["event"]), 1) -- only one event
assert.is_true(mock_expect_event("osquery_linux_installed_error"))
end)
end)
end
if ffi.os == 'Linux' then
describe('installing osquery', function()
it('should install and configure osquery', function()
-- exec cmd + assert
assert.is_true(mock_expect_event("osquery_linux_installed_success"))
assert.is_true(mock_expect_event("osquery_linux_config_updated_success"))
end)
end)
describe('when osquery was unexpected stopped', function()
it('should start osquery', function()
assert.is_nil(mock_get_event_context("osquery_linux_unexpected_stopped"))
assert.is_nil(mock_get_event_context("osquery_linux_started_success"))
osquery_stop()
assert.is_true(mock_expect_event("osquery_linux_unexpected_stopped"))
assert.is_true(mock_expect_event("osquery_linux_started_success"))
end)
end)
describe('when osquery was unexpected removed', function()
it('should reinstall osquery', function()
assert.is_nil(mock_get_event_context("osquery_linux_unexpected_uninstalled"))
assert.is_nil(mock_get_event_context("osquery_linux_installed_success"))
osquery_uninstall()
assert.is_true(mock_expect_event("osquery_linux_unexpected_uninstalled"))
assert.is_true(mock_expect_event("osquery_linux_installed_success"))
end)
end)
describe('when module get command update_config in callback', function()
it('should start osquery', function()
assert.is_nil(mock_get_event_context("osquery_linux_config_updated_success"))
--assert.is_nil(mock_get_event_context("osquery_linux_installed_success"))
--local src, dst = __mock.mock_token, __mock.module_token
__mock:send_control("update_config")
--mock_command_update_config()
assert.is_true(mock_expect_event("osquery_linux_config_updated_success"))
end)
end)
end
end)
end)
+7
View File
@@ -975,4 +975,11 @@ __mock.send_action = function(self, src, dst, data, name)
end
return false
end
__mock.send_control = function(self, cmtype, data)
if self.module_callbacks.control ~= nil then
return self.module_callbacks.control(cmtype, data)
end
return false
end
---------------------------------------------------