Merge pull request #205 from draios/demo-improvements

Demo improvements
This commit is contained in:
Mark Stemm 2017-02-01 16:24:05 -08:00 committed by GitHub
commit 1afbaba632
5 changed files with 77 additions and 10 deletions

View File

@ -97,6 +97,8 @@ void exfiltration()
shadow.open("/etc/shadow");
printf("Reading /etc/shadow and sending to 10.5.2.6:8197...\n");
if(!shadow.is_open())
{
fprintf(stderr, "Could not open /etc/shadow for reading: %s", strerror(errno));
@ -219,7 +221,7 @@ void write_rpm_database() {
}
void spawn_shell() {
printf("Spawning a shell using system()...\n");
printf("Spawning a shell to run \"ls > /dev/null\" using system()...\n");
int rc;
if ((rc = system("ls > /dev/null")) != 0)
@ -259,6 +261,7 @@ void mkdir_binary_dirs() {
void change_thread_namespace() {
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
// bogus. It's the attempt to call it that will trigger the
// rule.
@ -268,6 +271,7 @@ void change_thread_namespace() {
void system_user_interactive() {
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.
if ((child = fork()) == 0)
{
@ -313,6 +317,8 @@ void system_procs_network_activity() {
void non_sudo_setuid() {
pid_t child;
printf("Forking a child that becomes \"daemon\" user and then \"root\"...\n");
// Fork a child and do everything in the child.
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},
{"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)
{
@ -394,9 +403,9 @@ void run_actions(map<string, action_t> &actions, int interval, bool once)
{
for (auto action : actions)
{
sleep(interval);
printf("***Action %s\n", action.first.c_str());
action.second();
sleep(interval);
}
if(once)
{
@ -428,7 +437,7 @@ int main(int argc, char **argv)
// Parse the args
//
while((op = getopt_long(argc, argv,
"ha:i:l:",
"ha:i:l:o",
long_options, &long_index)) != -1)
{
switch(op)
@ -437,12 +446,16 @@ int main(int argc, char **argv)
usage(argv[0]);
exit(1);
case 'a':
if((it = defined_actions.find(optarg)) == defined_actions.end())
// "all" is already implied
if (strcmp(optarg, "all") != 0)
{
fprintf(stderr, "No action with name \"%s\" known, exiting.\n", optarg);
exit(1);
if((it = defined_actions.find(optarg)) == defined_actions.end())
{
fprintf(stderr, "No action with name \"%s\" known, exiting.\n", optarg);
exit(1);
}
actions.insert(*it);
}
actions.insert(*it);
break;
case 'i':
interval = atoi(optarg);
@ -482,7 +495,13 @@ int main(int argc, char **argv)
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);

View File

@ -20,5 +20,4 @@ falco:
- /boot:/host/boot:ro
- /lib/modules:/host/lib/modules:ro
- /usr:/host/usr:ro
- ${PWD}/../../rules/falco_rules.yaml:/etc/falco_rules.yaml
tty: true

View File

@ -345,7 +345,8 @@
- macro: trusted_containers
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 gcr.io/google_containers/hyperkube or
container.image startswith gcr.io/google_containers/kube-proxy)

View File

@ -56,6 +56,16 @@ class FalcoTest(Test):
for rule in self.disabled_rules:
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)
if self.rules_warning == False:
self.rules_warning = sets.Set()
@ -161,6 +171,23 @@ class FalcoTest(Test):
if not events_detected > 0:
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):
for output in self.outputs:
# Open the provided file and match each line against the
@ -222,6 +249,8 @@ class FalcoTest(Test):
if len(self.rules_events) > 0:
self.check_rules_events(res)
self.check_detections(res)
if len(self.detect_counts) > 0:
self.check_detections_by_rule(res)
self.check_json_output(res)
self.check_outputs()
pass

View File

@ -181,3 +181,22 @@ trace_files: !mux
trace_file: trace_files/cat_write.scap
outputs:
- /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