mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-30 16:42:14 +00:00
Merge pull request #205 from draios/demo-improvements
Demo improvements
This commit is contained in:
commit
1afbaba632
@ -97,6 +97,8 @@ void exfiltration()
|
|||||||
|
|
||||||
shadow.open("/etc/shadow");
|
shadow.open("/etc/shadow");
|
||||||
|
|
||||||
|
printf("Reading /etc/shadow and sending to 10.5.2.6:8197...\n");
|
||||||
|
|
||||||
if(!shadow.is_open())
|
if(!shadow.is_open())
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Could not open /etc/shadow for reading: %s", strerror(errno));
|
fprintf(stderr, "Could not open /etc/shadow for reading: %s", strerror(errno));
|
||||||
@ -219,7 +221,7 @@ void write_rpm_database() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spawn_shell() {
|
void spawn_shell() {
|
||||||
printf("Spawning a shell using system()...\n");
|
printf("Spawning a shell to run \"ls > /dev/null\" using system()...\n");
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if ((rc = system("ls > /dev/null")) != 0)
|
if ((rc = system("ls > /dev/null")) != 0)
|
||||||
@ -259,6 +261,7 @@ void mkdir_binary_dirs() {
|
|||||||
|
|
||||||
void change_thread_namespace() {
|
void change_thread_namespace() {
|
||||||
printf("Calling setns() to change namespaces...\n");
|
printf("Calling setns() to change namespaces...\n");
|
||||||
|
printf("NOTE: does not result in a falco notification in containers, unless container run with --privileged or --security-opt seccomp=unconfined\n");
|
||||||
// It doesn't matter that the arguments to setns are
|
// It doesn't matter that the arguments to setns are
|
||||||
// bogus. It's the attempt to call it that will trigger the
|
// bogus. It's the attempt to call it that will trigger the
|
||||||
// rule.
|
// rule.
|
||||||
@ -268,6 +271,7 @@ void change_thread_namespace() {
|
|||||||
void system_user_interactive() {
|
void system_user_interactive() {
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
|
||||||
|
printf("Forking a child that becomes user=daemon and then tries to run /bin/login...\n");
|
||||||
// Fork a child and do everything in the child.
|
// Fork a child and do everything in the child.
|
||||||
if ((child = fork()) == 0)
|
if ((child = fork()) == 0)
|
||||||
{
|
{
|
||||||
@ -313,6 +317,8 @@ void system_procs_network_activity() {
|
|||||||
void non_sudo_setuid() {
|
void non_sudo_setuid() {
|
||||||
pid_t child;
|
pid_t child;
|
||||||
|
|
||||||
|
printf("Forking a child that becomes \"daemon\" user and then \"root\"...\n");
|
||||||
|
|
||||||
// Fork a child and do everything in the child.
|
// Fork a child and do everything in the child.
|
||||||
if ((child = fork()) == 0)
|
if ((child = fork()) == 0)
|
||||||
{
|
{
|
||||||
@ -367,6 +373,9 @@ map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
|
|||||||
{"user_mgmt_binaries", user_mgmt_binaries},
|
{"user_mgmt_binaries", user_mgmt_binaries},
|
||||||
{"exfiltration", exfiltration}};
|
{"exfiltration", exfiltration}};
|
||||||
|
|
||||||
|
// Some actions don't directly result in suspicious behavior. These
|
||||||
|
// actions are excluded from the ones run with -a all.
|
||||||
|
set<string> exclude_from_all_actions = {"exec_ls", "network_activity"};
|
||||||
|
|
||||||
void create_symlinks(const char *program)
|
void create_symlinks(const char *program)
|
||||||
{
|
{
|
||||||
@ -394,9 +403,9 @@ void run_actions(map<string, action_t> &actions, int interval, bool once)
|
|||||||
{
|
{
|
||||||
for (auto action : actions)
|
for (auto action : actions)
|
||||||
{
|
{
|
||||||
sleep(interval);
|
|
||||||
printf("***Action %s\n", action.first.c_str());
|
printf("***Action %s\n", action.first.c_str());
|
||||||
action.second();
|
action.second();
|
||||||
|
sleep(interval);
|
||||||
}
|
}
|
||||||
if(once)
|
if(once)
|
||||||
{
|
{
|
||||||
@ -428,7 +437,7 @@ int main(int argc, char **argv)
|
|||||||
// Parse the args
|
// Parse the args
|
||||||
//
|
//
|
||||||
while((op = getopt_long(argc, argv,
|
while((op = getopt_long(argc, argv,
|
||||||
"ha:i:l:",
|
"ha:i:l:o",
|
||||||
long_options, &long_index)) != -1)
|
long_options, &long_index)) != -1)
|
||||||
{
|
{
|
||||||
switch(op)
|
switch(op)
|
||||||
@ -437,12 +446,16 @@ int main(int argc, char **argv)
|
|||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
case 'a':
|
case 'a':
|
||||||
|
// "all" is already implied
|
||||||
|
if (strcmp(optarg, "all") != 0)
|
||||||
|
{
|
||||||
if((it = defined_actions.find(optarg)) == defined_actions.end())
|
if((it = defined_actions.find(optarg)) == defined_actions.end())
|
||||||
{
|
{
|
||||||
fprintf(stderr, "No action with name \"%s\" known, exiting.\n", optarg);
|
fprintf(stderr, "No action with name \"%s\" known, exiting.\n", optarg);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
actions.insert(*it);
|
actions.insert(*it);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
interval = atoi(optarg);
|
interval = atoi(optarg);
|
||||||
@ -482,7 +495,13 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if(actions.size() == 0)
|
if(actions.size() == 0)
|
||||||
{
|
{
|
||||||
actions = defined_actions;
|
for(auto &act : defined_actions)
|
||||||
|
{
|
||||||
|
if(exclude_from_all_actions.find(act.first) == exclude_from_all_actions.end())
|
||||||
|
{
|
||||||
|
actions.insert(act);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
@ -20,5 +20,4 @@ falco:
|
|||||||
- /boot:/host/boot:ro
|
- /boot:/host/boot:ro
|
||||||
- /lib/modules:/host/lib/modules:ro
|
- /lib/modules:/host/lib/modules:ro
|
||||||
- /usr:/host/usr:ro
|
- /usr:/host/usr:ro
|
||||||
- ${PWD}/../../rules/falco_rules.yaml:/etc/falco_rules.yaml
|
|
||||||
tty: true
|
tty: true
|
||||||
|
@ -345,7 +345,8 @@
|
|||||||
|
|
||||||
- macro: trusted_containers
|
- macro: trusted_containers
|
||||||
condition: (container.image startswith sysdig/agent or
|
condition: (container.image startswith sysdig/agent or
|
||||||
container.image startswith sysdig/falco or
|
(container.image startswith sysdig/falco and
|
||||||
|
not container.image startswith sysdig/falco-event-generator) or
|
||||||
container.image startswith sysdig/sysdig or
|
container.image startswith sysdig/sysdig or
|
||||||
container.image startswith gcr.io/google_containers/hyperkube or
|
container.image startswith gcr.io/google_containers/hyperkube or
|
||||||
container.image startswith gcr.io/google_containers/kube-proxy)
|
container.image startswith gcr.io/google_containers/kube-proxy)
|
||||||
|
@ -56,6 +56,16 @@ class FalcoTest(Test):
|
|||||||
for rule in self.disabled_rules:
|
for rule in self.disabled_rules:
|
||||||
self.disabled_args = self.disabled_args + "-D " + rule + " "
|
self.disabled_args = self.disabled_args + "-D " + rule + " "
|
||||||
|
|
||||||
|
self.detect_counts = self.params.get('detect_counts', '*', default=False)
|
||||||
|
if self.detect_counts == False:
|
||||||
|
self.detect_counts = {}
|
||||||
|
else:
|
||||||
|
detect_counts = {}
|
||||||
|
for item in self.detect_counts:
|
||||||
|
for item2 in item:
|
||||||
|
detect_counts[item2[0]] = item2[1]
|
||||||
|
self.detect_counts = detect_counts
|
||||||
|
|
||||||
self.rules_warning = self.params.get('rules_warning', '*', default=False)
|
self.rules_warning = self.params.get('rules_warning', '*', default=False)
|
||||||
if self.rules_warning == False:
|
if self.rules_warning == False:
|
||||||
self.rules_warning = sets.Set()
|
self.rules_warning = sets.Set()
|
||||||
@ -161,6 +171,23 @@ class FalcoTest(Test):
|
|||||||
if not events_detected > 0:
|
if not events_detected > 0:
|
||||||
self.fail("Detected {} events at level {} when should have detected > 0".format(events_detected, level))
|
self.fail("Detected {} events at level {} when should have detected > 0".format(events_detected, level))
|
||||||
|
|
||||||
|
def check_detections_by_rule(self, res):
|
||||||
|
# Get the number of events detected for each rule. Must match the expected counts.
|
||||||
|
match = re.search('Triggered rules by rule name:(.*)', res.stdout, re.DOTALL)
|
||||||
|
if match is None:
|
||||||
|
self.fail("Could not find a block 'Triggered rules by rule name: ...' in falco output")
|
||||||
|
|
||||||
|
triggered_rules = match.group(1)
|
||||||
|
|
||||||
|
for rule, count in self.detect_counts.iteritems():
|
||||||
|
expected_line = '{}: {}'.format(rule, count)
|
||||||
|
match = re.search(expected_line, triggered_rules)
|
||||||
|
|
||||||
|
if match is None:
|
||||||
|
self.fail("Could not find a line '{}' in triggered rule counts '{}'".format(expected_line, triggered_rules))
|
||||||
|
else:
|
||||||
|
self.log.debug("Found expected count for {}: {}".format(rule, match.group()))
|
||||||
|
|
||||||
def check_outputs(self):
|
def check_outputs(self):
|
||||||
for output in self.outputs:
|
for output in self.outputs:
|
||||||
# Open the provided file and match each line against the
|
# Open the provided file and match each line against the
|
||||||
@ -222,6 +249,8 @@ class FalcoTest(Test):
|
|||||||
if len(self.rules_events) > 0:
|
if len(self.rules_events) > 0:
|
||||||
self.check_rules_events(res)
|
self.check_rules_events(res)
|
||||||
self.check_detections(res)
|
self.check_detections(res)
|
||||||
|
if len(self.detect_counts) > 0:
|
||||||
|
self.check_detections_by_rule(res)
|
||||||
self.check_json_output(res)
|
self.check_json_output(res)
|
||||||
self.check_outputs()
|
self.check_outputs()
|
||||||
pass
|
pass
|
||||||
|
@ -181,3 +181,22 @@ trace_files: !mux
|
|||||||
trace_file: trace_files/cat_write.scap
|
trace_file: trace_files/cat_write.scap
|
||||||
outputs:
|
outputs:
|
||||||
- /tmp/falco_outputs/program_output.txt: Warning An open was seen
|
- /tmp/falco_outputs/program_output.txt: Warning An open was seen
|
||||||
|
|
||||||
|
detect_counts:
|
||||||
|
detect: True
|
||||||
|
detect_level: WARNING
|
||||||
|
trace_file: traces-positive/falco-event-generator.scap
|
||||||
|
detect_counts:
|
||||||
|
- "Write below binary dir": 1
|
||||||
|
- "Read sensitive file untrusted": 3
|
||||||
|
- "Run shell in container": 1
|
||||||
|
- "Write below rpm database": 1
|
||||||
|
- "Write below etc": 1
|
||||||
|
- "System procs network activity": 1
|
||||||
|
- "Mkdir binary dirs": 1
|
||||||
|
- "System user interactive": 1
|
||||||
|
- "DB program spawned process": 1
|
||||||
|
- "Non sudo setuid": 1
|
||||||
|
- "Create files below dev": 1
|
||||||
|
- "Modify binary dirs": 2
|
||||||
|
- "Change thread namespace": 2
|
||||||
|
Loading…
Reference in New Issue
Block a user