Merge pull request #98 from draios/add-lists

Add list support to rules file.
This commit is contained in:
Mark Stemm 2016-07-11 16:05:29 -07:00 committed by GitHub
commit 8225dc0762
3 changed files with 94 additions and 67 deletions

View File

@ -63,76 +63,76 @@
- macro: linux_so_dirs - macro: linux_so_dirs
condition: ubuntu_so_dirs or centos_so_dirs or fd.name=/etc/ld.so.cache condition: ubuntu_so_dirs or centos_so_dirs or fd.name=/etc/ld.so.cache
- macro: coreutils_binaries - list: coreutils_binaries
condition: > items: [
proc.name in (truncate, sha1sum, numfmt, fmt, fold, uniq, cut, who, truncate, sha1sum, numfmt, fmt, fold, uniq, cut, who,
groups, csplit, sort, expand, printf, printenv, unlink, tee, chcon, stat, 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, base64, unexpand, cksum, od, paste, nproc, pathchk, sha256sum, wc, test,
comm, arch, du, factor, sha512sum, md5sum, tr, runcon, env, dirname, comm, arch, du, factor, sha512sum, md5sum, tr, runcon, env, dirname,
tsort, join, shuf, install, logname, pinky, nohup, expr, pr, tty, timeout, tsort, join, shuf, install, logname, pinky, nohup, expr, pr, tty, timeout,
tail, [, seq, sha384sum, nl, head, id, mkfifo, sum, dircolors, ptx, shred, tail, "[", seq, sha384sum, nl, head, id, mkfifo, sum, dircolors, ptx, shred,
tac, link, chroot, vdir, chown, touch, ls, dd, uname, true, pwd, date, tac, link, chroot, vdir, chown, touch, ls, dd, uname, "true", pwd, date,
chgrp, chmod, mktemp, cat, mknod, sync, ln, false, rm, mv, cp, echo, chgrp, chmod, mktemp, cat, mknod, sync, ln, "false", rm, mv, cp, echo,
readlink, sleep, stty, mkdir, df, dir, rmdir, touch) 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" "," # dpkg -L login | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
- macro: login_binaries - list: login_binaries
condition: proc.name in (login, systemd-logind, su, nologin, faillog, lastlog, newgrp, sg) 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" "," # dpkg -L passwd | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
- macro: passwd_binaries - list: passwd_binaries
condition: > items: [
proc.name in (shadowconfig, grpck, pwunconv, grpconv, pwck, shadowconfig, grpck, pwunconv, grpconv, pwck,
groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod, groupmod, vipw, pwconv, useradd, newusers, cppw, chpasswd, usermod,
groupadd, groupdel, grpunconv, chgpasswd, userdel, chage, chsh, 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" "," # repoquery -l shadow-utils | grep bin | xargs ls -ld | grep -v '^d' | awk '{print $9}' | xargs -L 1 basename | tr "\\n" ","
- macro: shadowutils_binaries - list: shadowutils_binaries
condition: > items: [
proc.name in (chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd, chage, gpasswd, lastlog, newgrp, sg, adduser, deluser, chpasswd,
groupadd, groupdel, addgroup, delgroup, groupmems, groupmod, grpck, grpconv, grpunconv, 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 - list: sysdigcloud_binaries
condition: proc.name in (setup-backend, dragent) items: [setup-backend, dragent]
- macro: sysdigcloud_binaries_parent - list: docker_binaries
condition: proc.pname in (setup-backend, dragent) items: [docker, exe]
- macro: docker_binaries - list: http_server_binaries
condition: proc.name in (docker, exe) items: [nginx, httpd, httpd-foregroun, lighttpd]
- macro: http_server_binaries - list: db_server_binaries
condition: proc.name in (nginx, httpd, httpd-foregroun, lighttpd) items: [mysqld]
- macro: db_server_binaries - macro: server_procs
condition: proc.name in (mysqld) condition: proc.name in (http_server_binaries, db_server_binaries, docker_binaries, sshd)
- 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))
# The truncated dpkg-preconfigu is intentional, process names are # The truncated dpkg-preconfigu is intentional, process names are
# truncated at the sysdig level. # truncated at the sysdig level.
- macro: package_mgmt_binaries - list: package_mgmt_binaries
condition: proc.name in (dpkg, dpkg-preconfigu, rpm, rpmkey, yum) 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 # A canonical set of processes that run other programs with different
# privileges or as a different user. # privileges or as a different user.
- macro: userexec_binaries - list: userexec_binaries
condition: proc.name in (sudo, su) items: [sudo, su]
- macro: user_mgmt_binaries - list: user_mgmt_binaries
condition: (login_binaries or passwd_binaries or shadowutils_binaries) items: [login_binaries, passwd_binaries, shadowutils_binaries]
- macro: system_binaries - macro: system_procs
condition: (coreutils_binaries or user_mgmt_binaries) condition: proc.name in (coreutils_binaries, user_mgmt_binaries)
- macro: mail_binaries - macro: mail_procs
condition: proc.name in (sendmail, sendmail-msp, postfix, procmail) condition: proc.name in (sendmail, sendmail-msp, postfix, procmail)
- macro: sensitive_files - macro: sensitive_files
@ -167,10 +167,8 @@
condition: ((proc.aname=sshd and proc.name != sshd) or proc.name=systemd-logind) condition: ((proc.aname=sshd and proc.name != sshd) or proc.name=systemd-logind)
- macro: syslog - macro: syslog
condition: fd.name in (/dev/log, /run/systemd/journal/syslog) condition: fd.name in (/dev/log, /run/systemd/journal/syslog)
- macro: cron - list: cron_binaries
condition: proc.name in (cron, crond) items: [cron, crond]
- macro: parent_cron
condition: proc.pname in (cron, crond)
# System users that should never log into a system. Consider adding your own # System users that should never log into a system. Consider adding your own
# service users (e.g. 'apache' or 'mysqld') here. # service users (e.g. 'apache' or 'mysqld') here.
@ -184,32 +182,32 @@
- rule: write_binary_dir - rule: write_binary_dir
desc: an attempt to write to any file below a set of binary directories 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)" output: "File below a known binary directory opened for writing (user=%user.name command=%proc.cmdline file=%fd.name)"
priority: WARNING priority: WARNING
- rule: write_etc - rule: write_etc
desc: an attempt to write to any file below /etc, not in a pipe installer session 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)" output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name)"
priority: WARNING priority: WARNING
# Within a fbash session, the severity is lowered to INFO # Within a fbash session, the severity is lowered to INFO
- rule: write_etc_installer - rule: write_etc_installer
desc: an attempt to write to any file below /etc, in a pipe installer session 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" output: "File below /etc opened for writing (user=%user.name command=%proc.cmdline file=%fd.name) within pipe installer session"
priority: INFO priority: INFO
- rule: read_sensitive_file_untrusted - 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. 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)" output: "Sensitive file opened for reading by non-trusted program (user=%user.name command=%proc.cmdline file=%fd.name)"
priority: WARNING priority: WARNING
- rule: read_sensitive_file_trusted_after_startup - 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. 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)" output: "Sensitive file opened for reading by trusted program after startup (user=%user.name command=%proc.cmdline file=%fd.name)"
priority: WARNING priority: WARNING
@ -222,19 +220,19 @@
- rule: db_program_spawned_process - 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. 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)" output: "Database-related program spawned process other than itself (user=%user.name program=%proc.cmdline parent=%proc.pname)"
priority: WARNING priority: WARNING
- rule: modify_binary_dirs - rule: modify_binary_dirs
desc: an attempt to modify any file below a set of binary directories. 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)" output: "File below known binary directory renamed/removed (user=%user.name command=%proc.cmdline operation=%evt.type file=%fd.name %evt.args)"
priority: WARNING priority: WARNING
- rule: mkdir_binary_dirs - rule: mkdir_binary_dirs
desc: an attempt to create a directory below a set of binary directories. 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)" output: "Directory below known binary directory created (user=%user.name command=%proc.cmdline directory=%evt.arg.path)"
priority: WARNING priority: WARNING
@ -262,7 +260,7 @@
- rule: run_shell_untrusted - rule: run_shell_untrusted
desc: an attempt to spawn a shell by a non-shell program. Exceptions are made for trusted binaries. 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)" output: "Shell spawned by untrusted binary (user=%user.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline)"
priority: WARNING priority: WARNING
@ -284,9 +282,9 @@
priority: WARNING priority: WARNING
# sockfamily ip is to exclude certain processes (like 'groups') that communicate on unix-domain sockets # 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 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)" output: "Known system binary sent/received network traffic (user=%user.name command=%proc.cmdline connection=%fd.name)"
priority: WARNING 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 # 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 - 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. 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)" output: "Unexpected setuid call by non-sudo, non-root program (user=%user.name command=%proc.cmdline uid=%evt.arg.uid)"
priority: WARNING priority: WARNING
- rule: user_mgmt_binaries - 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. 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)" output: "User management binary command run outside of container (user=%user.name command=%proc.cmdline parent=%proc.pname)"
priority: WARNING priority: WARNING
@ -356,7 +354,7 @@
# as a part of doing the installation # as a part of doing the installation
- rule: installer_bash_runs_pkgmgmt - rule: installer_bash_runs_pkgmgmt
desc: an attempt by a program in a pipe installer session to run a package management binary 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)" output: "Package management program run by process in a fbash session (command=%proc.cmdline)"
priority: INFO priority: INFO
@ -525,6 +523,6 @@
# - rule: http_server_unexpected_network_inbound # - rule: http_server_unexpected_network_inbound
# desc: inbound network traffic to a http server program on a port other than the standard ports # 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)" # output: "Inbound network traffic to HTTP Server on unexpected port (connection=%fd.name)"
# priority: WARNING # priority: WARNING

View File

@ -156,7 +156,12 @@ function check_for_ignored_syscalls_events(ast, filter_type, source)
parser.traverse_ast(ast, "BinaryRelOp", cb) parser.traverse_ast(ast, "BinaryRelOp", cb)
end 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) local ast, error_msg = parser.parse_filter(line)
if (error_msg) then 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. 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) local ast, error_msg = parser.parse_filter(source)
if (error_msg) then if (error_msg) then

View File

@ -115,7 +115,7 @@ end
-- object. The by_name index is used for things like describing rules, -- 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 -- and the by_idx index is used to map the relational node index back
-- to a rule. -- 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) function load_rules(filename)
@ -131,9 +131,28 @@ function load_rules(filename)
end end
if (v['macro']) then 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 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 else -- rule
if (v['rule'] == nil) then if (v['rule'] == nil) then
@ -150,7 +169,7 @@ function load_rules(filename)
v['level'] = priority(v['priority']) v['level'] = priority(v['priority'])
state.rules_by_name[v['rule']] = v 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 if (filter_ast.type == "Rule") then
state.n_rules = state.n_rules + 1 state.n_rules = state.n_rules + 1