mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-31 06:01:52 +00:00
Merge pull request #98 from draios/add-lists
Add list support to rules file.
This commit is contained in:
commit
8225dc0762
@ -63,76 +63,76 @@
|
||||
- macro: linux_so_dirs
|
||||
condition: ubuntu_so_dirs or centos_so_dirs or fd.name=/etc/ld.so.cache
|
||||
|
||||
- macro: coreutils_binaries
|
||||
condition: >
|
||||
proc.name in (truncate, sha1sum, numfmt, fmt, fold, uniq, cut, who,
|
||||
- list: coreutils_binaries
|
||||
items: [
|
||||
truncate, sha1sum, numfmt, fmt, fold, uniq, cut, who,
|
||||
groups, csplit, sort, expand, printf, printenv, unlink, tee, chcon, stat,
|
||||
basename, split, nice, yes, whoami, sha224sum, hostid, users, stdbuf,
|
||||
basename, split, nice, "yes", whoami, sha224sum, hostid, users, stdbuf,
|
||||
base64, unexpand, cksum, od, paste, nproc, pathchk, sha256sum, wc, test,
|
||||
comm, arch, du, factor, sha512sum, md5sum, tr, runcon, env, dirname,
|
||||
tsort, join, shuf, install, logname, pinky, nohup, expr, pr, tty, timeout,
|
||||
tail, [, seq, sha384sum, nl, head, id, mkfifo, sum, dircolors, ptx, shred,
|
||||
tac, link, chroot, vdir, chown, touch, ls, dd, uname, true, pwd, date,
|
||||
chgrp, chmod, mktemp, cat, mknod, sync, ln, false, rm, mv, cp, echo,
|
||||
readlink, sleep, stty, mkdir, df, dir, rmdir, touch)
|
||||
tail, "[", seq, sha384sum, nl, head, id, mkfifo, sum, dircolors, ptx, shred,
|
||||
tac, link, chroot, vdir, chown, touch, ls, dd, uname, "true", pwd, date,
|
||||
chgrp, chmod, mktemp, cat, mknod, sync, ln, "false", rm, mv, cp, echo,
|
||||
readlink, sleep, stty, mkdir, df, dir, rmdir, touch
|
||||
]
|
||||
|
||||
# dpkg -L login | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
|
||||
- macro: login_binaries
|
||||
condition: proc.name in (login, systemd-logind, su, nologin, faillog, lastlog, newgrp, sg)
|
||||
- list: login_binaries
|
||||
items: [login, systemd-logind, su, nologin, faillog, lastlog, newgrp, sg]
|
||||
|
||||
# dpkg -L passwd | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
|
||||
- macro: passwd_binaries
|
||||
condition: >
|
||||
proc.name in (shadowconfig, grpck, pwunconv, grpconv, pwck,
|
||||
- list: passwd_binaries
|
||||
items: [
|
||||
shadowconfig, grpck, pwunconv, grpconv, pwck,
|
||||
groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod,
|
||||
groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh,
|
||||
gpasswd, chfn, expiry, passwd, vigr, cpgr)
|
||||
gpasswd, chfn, expiry, passwd, vigr, cpgr
|
||||
]
|
||||
|
||||
# repoquery -l shadow-utils | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
|
||||
- macro: shadowutils_binaries
|
||||
condition: >
|
||||
proc.name in (chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd,
|
||||
- list: shadowutils_binaries
|
||||
items: [
|
||||
chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd,
|
||||
groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, grpconv, grpunconv,
|
||||
newusers, pwck, pwconv, pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd)
|
||||
newusers, pwck, pwconv, pwunconv, useradd, userdel, usermod, vigr, vipw, unix_chkpwd
|
||||
]
|
||||
|
||||
- macro: sysdigcloud_binaries
|
||||
condition: proc.name in (setup-backend, dragent)
|
||||
- list: sysdigcloud_binaries
|
||||
items: [setup-backend, dragent]
|
||||
|
||||
- macro: sysdigcloud_binaries_parent
|
||||
condition: proc.pname in (setup-backend, dragent)
|
||||
- list: docker_binaries
|
||||
items: [docker, exe]
|
||||
|
||||
- macro: docker_binaries
|
||||
condition: proc.name in (docker, exe)
|
||||
- list: http_server_binaries
|
||||
items: [nginx, httpd, httpd-foregroun, lighttpd]
|
||||
|
||||
- macro: http_server_binaries
|
||||
condition: proc.name in (nginx, httpd, httpd-foregroun, lighttpd)
|
||||
- list: db_server_binaries
|
||||
items: [mysqld]
|
||||
|
||||
- macro: db_server_binaries
|
||||
condition: proc.name in (mysqld)
|
||||
|
||||
- macro: db_server_binaries_parent
|
||||
condition: proc.pname in (mysqld)
|
||||
|
||||
- macro: server_binaries
|
||||
condition: (http_server_binaries or db_server_binaries or docker_binaries or proc.name in (sshd))
|
||||
- macro: server_procs
|
||||
condition: proc.name in (http_server_binaries, db_server_binaries, docker_binaries, sshd)
|
||||
|
||||
# The truncated dpkg-preconfigu is intentional, process names are
|
||||
# truncated at the sysdig level.
|
||||
- macro: package_mgmt_binaries
|
||||
condition: proc.name in (dpkg, dpkg-preconfigu, rpm, rpmkey, yum)
|
||||
- list: package_mgmt_binaries
|
||||
items: [dpkg, dpkg-preconfigu, rpm, rpmkey, yum]
|
||||
|
||||
- macro: package_mgmt_procs
|
||||
condition: proc.name in (package_mgmt_binaries)
|
||||
|
||||
# A canonical set of processes that run other programs with different
|
||||
# privileges or as a different user.
|
||||
- macro: userexec_binaries
|
||||
condition: proc.name in (sudo, su)
|
||||
- list: userexec_binaries
|
||||
items: [sudo, su]
|
||||
|
||||
- macro: user_mgmt_binaries
|
||||
condition: (login_binaries or passwd_binaries or shadowutils_binaries)
|
||||
- list: user_mgmt_binaries
|
||||
items: [login_binaries, passwd_binaries, shadowutils_binaries]
|
||||
|
||||
- macro: system_binaries
|
||||
condition: (coreutils_binaries or user_mgmt_binaries)
|
||||
- macro: system_procs
|
||||
condition: proc.name in (coreutils_binaries, user_mgmt_binaries)
|
||||
|
||||
- macro: mail_binaries
|
||||
- macro: mail_procs
|
||||
condition: proc.name in (sendmail, sendmail-msp, postfix, procmail)
|
||||
|
||||
- macro: sensitive_files
|
||||
@ -167,10 +167,8 @@
|
||||
condition: ((proc.aname=sshd and proc.name != sshd) or proc.name=systemd-logind)
|
||||
- macro: syslog
|
||||
condition: fd.name in (/dev/log, /run/systemd/journal/syslog)
|
||||
- macro: cron
|
||||
condition: proc.name in (cron, crond)
|
||||
- macro: parent_cron
|
||||
condition: proc.pname in (cron, crond)
|
||||
- list: cron_binaries
|
||||
items: [cron, crond]
|
||||
|
||||
# System users that should never log into a system. Consider adding your own
|
||||
# service users (e.g. 'apache' or 'mysqld') here.
|
||||
@ -184,32 +182,32 @@
|
||||
|
||||
- rule: write_binary_dir
|
||||
desc: an attempt to write to any file below a set of binary directories
|
||||
condition: evt.dir = < and open_write and not package_mgmt_binaries and bin_dir
|
||||
condition: evt.dir = < and open_write and not package_mgmt_procs and bin_dir
|
||||
output: "File below a known binary directory opened for writing (user=%user.name command=%proc.cmdline file=%fd.name)"
|
||||
priority: WARNING
|
||||
|
||||
- rule: write_etc
|
||||
desc: an attempt to write to any file below /etc, not in a pipe installer session
|
||||
condition: evt.dir = < and open_write and not shadowutils_binaries and not sysdigcloud_binaries_parent and not package_mgmt_binaries and etc_dir and not proc.sname=fbash
|
||||
condition: evt.dir = < and open_write and not proc.name in (shadowutils_binaries, sysdigcloud_binaries, package_mgmt_binaries) and etc_dir and not proc.pname in (sysdigcloud_binaries) and not proc.sname=fbash
|
||||
output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name)"
|
||||
priority: WARNING
|
||||
|
||||
# Within a fbash session, the severity is lowered to INFO
|
||||
- rule: write_etc_installer
|
||||
desc: an attempt to write to any file below /etc, in a pipe installer session
|
||||
condition: evt.dir = < and open_write and not shadowutils_binaries and not sysdigcloud_binaries_parent and not package_mgmt_binaries and etc_dir and proc.sname=fbash
|
||||
condition: evt.dir = < and open_write and not proc.name in (shadowutils_binaries, sysdigcloud_binaries, package_mgmt_binaries) and etc_dir and not proc.pname in (sysdigcloud_binaries) and proc.sname=fbash
|
||||
output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name) within pipe installer session"
|
||||
priority: INFO
|
||||
|
||||
- rule: read_sensitive_file_untrusted
|
||||
desc: an attempt to read any sensitive file (e.g. files containing user/password/authentication information). Exceptions are made for known trusted programs.
|
||||
condition: open_read and not user_mgmt_binaries and not userexec_binaries and not proc.name in (iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon, bash, sshd) and not cron and sensitive_files
|
||||
condition: open_read and not proc.name in (user_mgmt_binaries, userexec_binaries, cron_binaries, iptables, ps, lsb_release, check-new-relea, dumpe2fs, accounts-daemon, bash, sshd) and sensitive_files
|
||||
output: "Sensitive file opened for reading by non-trusted program (user=%user.name command=%proc.cmdline file=%fd.name)"
|
||||
priority: WARNING
|
||||
|
||||
- rule: read_sensitive_file_trusted_after_startup
|
||||
desc: an attempt to read any sensitive file (e.g. files containing user/password/authentication information) by a trusted program after startup. Trusted programs might read these files at startup to load initial state, but not afterwards.
|
||||
condition: open_read and server_binaries and not proc_is_new and sensitive_files and proc.name!="sshd"
|
||||
condition: open_read and server_procs and not proc_is_new and sensitive_files and proc.name!="sshd"
|
||||
output: "Sensitive file opened for reading by trusted program after startup (user=%user.name command=%proc.cmdline file=%fd.name)"
|
||||
priority: WARNING
|
||||
|
||||
@ -222,19 +220,19 @@
|
||||
|
||||
- rule: db_program_spawned_process
|
||||
desc: a database-server related program spawned a new process other than itself. This shouldn\'t occur and is a follow on from some SQL injection attacks.
|
||||
condition: db_server_binaries_parent and not db_server_binaries and spawned_process
|
||||
condition: proc.pname in (db_server_binaries) and not proc.name in (db_server_binaries) and spawned_process
|
||||
output: "Database-related program spawned process other than itself (user=%user.name program=%proc.cmdline parent=%proc.pname)"
|
||||
priority: WARNING
|
||||
|
||||
- rule: modify_binary_dirs
|
||||
desc: an attempt to modify any file below a set of binary directories.
|
||||
condition: modify and bin_dir_rename and not package_mgmt_binaries
|
||||
condition: modify and bin_dir_rename and not package_mgmt_procs
|
||||
output: "File below known binary directory renamed/removed (user=%user.name command=%proc.cmdline operation=%evt.type file=%fd.name %evt.args)"
|
||||
priority: WARNING
|
||||
|
||||
- rule: mkdir_binary_dirs
|
||||
desc: an attempt to create a directory below a set of binary directories.
|
||||
condition: mkdir and bin_dir_mkdir and not package_mgmt_binaries
|
||||
condition: mkdir and bin_dir_mkdir and not package_mgmt_procs
|
||||
output: "Directory below known binary directory created (user=%user.name command=%proc.cmdline directory=%evt.arg.path)"
|
||||
priority: WARNING
|
||||
|
||||
@ -262,7 +260,7 @@
|
||||
|
||||
- rule: run_shell_untrusted
|
||||
desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries.
|
||||
condition: not container and proc.name = bash and spawned_process and proc.pname exists and not parent_cron and not proc.pname in (bash, sshd, sudo, docker, su, tmux, screen, emacs, systemd, login, flock, fbash, nginx, monit, supervisord, dragent)
|
||||
condition: not container and proc.name = bash and spawned_process and proc.pname exists and not proc.pname in (cron_binaries, bash, sshd, sudo, docker, su, tmux, screen, emacs, systemd, login, flock, fbash, nginx, monit, supervisord, dragent)
|
||||
output: "Shell spawned by untrusted binary (user=%user.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)"
|
||||
priority: WARNING
|
||||
|
||||
@ -284,9 +282,9 @@
|
||||
priority: WARNING
|
||||
|
||||
# sockfamily ip is to exclude certain processes (like 'groups') that communicate on unix-domain sockets
|
||||
- rule: system_binaries_network_activity
|
||||
- rule: system_procs_network_activity
|
||||
desc: any network activity performed by system binaries that are not expected to send or receive any network traffic
|
||||
condition: (inbound or outbound) and (fd.sockfamily = ip and system_binaries)
|
||||
condition: (inbound or outbound) and (fd.sockfamily = ip and system_procs)
|
||||
output: "Known system binary sent/received network traffic (user=%user.name command=%proc.cmdline connection=%fd.name)"
|
||||
priority: WARNING
|
||||
|
||||
@ -302,13 +300,13 @@
|
||||
# sshd, sendmail-msp, sendmail attempt to setuid to root even when running as non-root. Excluding here to avoid meaningless FPs
|
||||
- rule: non_sudo_setuid
|
||||
desc: an attempt to change users by calling setuid. sudo/su are excluded. user "root" is also excluded, as setuid calls typically involve dropping privileges.
|
||||
condition: evt.type=setuid and evt.dir=> and not user.name=root and not userexec_binaries and not proc.name in (sshd, sendmail-msp, sendmail)
|
||||
condition: evt.type=setuid and evt.dir=> and not user.name=root and not proc.name in (userexec_binaries, sshd, sendmail-msp, sendmail)
|
||||
output: "Unexpected setuid call by non-sudo, non-root program (user=%user.name command=%proc.cmdline uid=%evt.arg.uid)"
|
||||
priority: WARNING
|
||||
|
||||
- rule: user_mgmt_binaries
|
||||
desc: activity by any programs that can manage users, passwords, or permissions. sudo and su are excluded. Activity in containers is also excluded--some containers create custom users on top of a base linux distribution at startup.
|
||||
condition: spawned_process and not proc.name in (su, sudo) and not container and user_mgmt_binaries and not parent_cron and not proc.pname in (systemd, run-parts)
|
||||
condition: spawned_process and not proc.name in (su, sudo) and not container and proc.name in (user_mgmt_binaries) and not proc.pname in (cron_binaries, systemd, run-parts)
|
||||
output: "User management binary command run outside of container (user=%user.name command=%proc.cmdline parent=%proc.pname)"
|
||||
priority: WARNING
|
||||
|
||||
@ -356,7 +354,7 @@
|
||||
# as a part of doing the installation
|
||||
- rule: installer_bash_runs_pkgmgmt
|
||||
desc: an attempt by a program in a pipe installer session to run a package management binary
|
||||
condition: evt.type=execve and package_mgmt_binaries and proc.sname=fbash
|
||||
condition: evt.type=execve and package_mgmt_procs and proc.sname=fbash
|
||||
output: "Package management program run by process in a fbash session (command=%proc.cmdline)"
|
||||
priority: INFO
|
||||
|
||||
@ -525,6 +523,6 @@
|
||||
|
||||
# - rule: http_server_unexpected_network_inbound
|
||||
# desc: inbound network traffic to a http server program on a port other than the standard ports
|
||||
# condition: http_server_binaries and inbound and fd.sport != 80 and fd.sport != 443
|
||||
# condition: proc.name in (http_server_binaries) and inbound and fd.sport != 80 and fd.sport != 443
|
||||
# output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
|
||||
# priority: WARNING
|
||||
|
@ -156,7 +156,12 @@ function check_for_ignored_syscalls_events(ast, filter_type, source)
|
||||
parser.traverse_ast(ast, "BinaryRelOp", cb)
|
||||
end
|
||||
|
||||
function compiler.compile_macro(line)
|
||||
function compiler.compile_macro(line, list_defs)
|
||||
|
||||
for name, items in pairs(list_defs) do
|
||||
line = string.gsub(line, name, table.concat(items, ", "))
|
||||
end
|
||||
|
||||
local ast, error_msg = parser.parse_filter(line)
|
||||
|
||||
if (error_msg) then
|
||||
@ -174,7 +179,12 @@ end
|
||||
--[[
|
||||
Parses a single filter, then expands macros using passed-in table of definitions. Returns resulting AST.
|
||||
--]]
|
||||
function compiler.compile_filter(source, macro_defs)
|
||||
function compiler.compile_filter(source, macro_defs, list_defs)
|
||||
|
||||
for name, items in pairs(list_defs) do
|
||||
source = string.gsub(source, name, table.concat(items, ", "))
|
||||
end
|
||||
|
||||
local ast, error_msg = parser.parse_filter(source)
|
||||
|
||||
if (error_msg) then
|
||||
|
@ -115,7 +115,7 @@ end
|
||||
-- object. The by_name index is used for things like describing rules,
|
||||
-- and the by_idx index is used to map the relational node index back
|
||||
-- to a rule.
|
||||
local state = {macros={}, filter_ast=nil, rules_by_name={}, n_rules=0, rules_by_idx={}}
|
||||
local state = {macros={}, lists={}, filter_ast=nil, rules_by_name={}, n_rules=0, rules_by_idx={}}
|
||||
|
||||
function load_rules(filename)
|
||||
|
||||
@ -131,9 +131,28 @@ function load_rules(filename)
|
||||
end
|
||||
|
||||
if (v['macro']) then
|
||||
local ast = compiler.compile_macro(v['condition'])
|
||||
local ast = compiler.compile_macro(v['condition'], state.lists)
|
||||
state.macros[v['macro']] = ast.filter.value
|
||||
|
||||
elseif (v['list']) then
|
||||
-- list items are represented in yaml as a native list, so no
|
||||
-- parsing necessary
|
||||
local items = {}
|
||||
|
||||
-- List items may be references to other lists, so go through
|
||||
-- the items and expand any references to the items in the list
|
||||
for i, item in ipairs(v['items']) do
|
||||
if (state.lists[item] == nil) then
|
||||
items[#items+1] = item
|
||||
else
|
||||
for i, exp_item in ipairs(state.lists[item]) do
|
||||
items[#items+1] = exp_item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
state.lists[v['list']] = items
|
||||
|
||||
else -- rule
|
||||
|
||||
if (v['rule'] == nil) then
|
||||
@ -150,7 +169,7 @@ function load_rules(filename)
|
||||
v['level'] = priority(v['priority'])
|
||||
state.rules_by_name[v['rule']] = v
|
||||
|
||||
local filter_ast = compiler.compile_filter(v['condition'], state.macros)
|
||||
local filter_ast = compiler.compile_filter(v['condition'], state.macros, state.lists)
|
||||
|
||||
if (filter_ast.type == "Rule") then
|
||||
state.n_rules = state.n_rules + 1
|
||||
|
Loading…
Reference in New Issue
Block a user