From 8ff22773c3f4943a9c3aedbcb9e61313b7eaf93e Mon Sep 17 00:00:00 2001 From: Jaehyun Nam Date: Mon, 28 Feb 2022 17:30:22 +0000 Subject: [PATCH] get full paths Signed-off-by: Jaehyun Nam --- .github/workflows/ci-test.yml | 5 +- KubeArmor/BPF/system_monitor.c | 192 ++++++++++++------ KubeArmor/core/containerdHandler.go | 4 +- KubeArmor/core/dockerHandler.go | 4 +- KubeArmor/feeder/feeder.go | 10 +- KubeArmor/monitor/hostProcessTree.go | 65 ------ KubeArmor/monitor/logUpdate.go | 23 ++- KubeArmor/monitor/processTree.go | 126 ++++++------ KubeArmor/monitor/syscallParser.go | 2 +- KubeArmor/monitor/systemMonitor.go | 95 +++++---- KubeArmor/types/types.go | 15 +- contribution/self-managed-k8s/setup.sh | 2 +- ...sp-kubearmor-dev-next-proc-path-block.yaml | 2 +- .../hsp-kubearmor-dev-proc-path-block.yaml | 2 +- ...oup-2-file-path-block-from-source-dir.yaml | 18 -- ...up-2-file-path-block-from-source-path.yaml | 2 +- ...-path-readonly-audit-from-source-path.yaml | 4 +- .../sep-ubuntu-3-file-allow.yaml | 15 -- protobuf/kubearmor.pb.go | 134 +++++++----- protobuf/kubearmor.proto | 6 + .../kubearmor-dev-next_test_1/cmd1 | 6 +- .../kubearmor-dev-next_test_2/cmd1 | 2 +- .../host_scenarios/kubearmor-dev_test_1/cmd1 | 6 +- .../host_scenarios/kubearmor-dev_test_2/cmd1 | 2 +- tests/test-scenarios-github.sh | 4 +- tests/test-scenarios-local.sh | 4 +- 26 files changed, 403 insertions(+), 347 deletions(-) delete mode 100644 KubeArmor/monitor/hostProcessTree.go delete mode 100644 examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-dir.yaml delete mode 100644 examples/multiubuntu/security-policies/sep-ubuntu-3-file-allow.yaml diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 44d2ab76ca..f34cc368c2 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -7,12 +7,14 @@ on: - 'KubeArmor/**' - 'tests/**' - 'protobuf/**' + - '.github/workflows/ci-test.yml' pull_request: branches: [main] paths: - 'KubeArmor/**' - 'tests/**' - 'protobuf/**' + - '.github/workflows/ci-test.yml' jobs: build: @@ -42,7 +44,8 @@ jobs: sudo apt-get update sudo apt-get -y install build-essential cmake bison flex git python3 python3-pip clang-9 libllvm9 llvm-9-dev libclang-9-dev zlib1g-dev libelf-dev libedit-dev libfl-dev pushd /tmp - git clone https://github.com/iovisor/bcc.git + # fetch latest bcc release + git clone --branch v0.24.0 --depth 1 https://github.com/iovisor/bcc.git mkdir -p bcc/build; cd bcc/build sudo ln -s /usr/lib/llvm-9 /usr/local/llvm cmake .. -DPYTHON_CMD=python3 -DCMAKE_INSTALL_PREFIX=/usr diff --git a/KubeArmor/BPF/system_monitor.c b/KubeArmor/BPF/system_monitor.c index 0746e1eddb..bdda068e95 100644 --- a/KubeArmor/BPF/system_monitor.c +++ b/KubeArmor/BPF/system_monitor.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,9 @@ enum { _SYS_EXECVE = 59, _SYS_EXECVEAT = 322, _DO_EXIT = 351, + + // lsm + _SECURITY_BPRM_CHECK = 352, }; typedef struct __attribute__((__packed__)) sys_context { @@ -117,7 +121,8 @@ typedef struct args { } args_t; BPF_HASH(args_map, u64, args_t); -BPF_HASH(path_map, u64, struct path); +BPF_HASH(exec_map, u64, struct path); +BPF_HASH(file_map, u64, struct path); typedef struct buffers { u8 buf[MAX_BUFFER_SIZE]; @@ -406,22 +411,23 @@ static __always_inline u32 init_context(sys_context_t *context) // == Buffer Management == // -#define DATA_BUFFER 0 -#define PATH_BUFFER 1 +#define DATA_BUF_TYPE 0 +#define EXEC_BUF_TYPE 1 +#define FILE_BUF_TYPE 2 -static __always_inline bufs_t* get_buffer(int idx) +static __always_inline bufs_t* get_buffer(int buf_type) { - return bufs.lookup(&idx); + return bufs.lookup(&buf_type); } -static __always_inline void set_buffer_offset(int idx, u32 off) +static __always_inline void set_buffer_offset(int buf_type, u32 off) { - bufs_offset.update(&idx, &off); + bufs_offset.update(&buf_type, &off); } -static __always_inline u32* get_buffer_offset(int idx) +static __always_inline u32* get_buffer_offset(int buf_type) { - return bufs_offset.lookup(&idx); + return bufs_offset.lookup(&buf_type); } static __always_inline int save_context_to_buffer(bufs_t *bufs_p, void *ptr) @@ -435,7 +441,7 @@ static __always_inline int save_context_to_buffer(bufs_t *bufs_p, void *ptr) static __always_inline int save_str_to_buffer(bufs_t *bufs_p, void *ptr) { - u32 *off = get_buffer_offset(DATA_BUFFER); + u32 *off = get_buffer_offset(DATA_BUF_TYPE); if (off == NULL) { return -1; } @@ -462,7 +468,7 @@ static __always_inline int save_str_to_buffer(bufs_t *bufs_p, void *ptr) bpf_probe_read(&(bufs_p->buf[*off]), sizeof(int), &sz); *off += sz + sizeof(int); - set_buffer_offset(DATA_BUFFER, *off); + set_buffer_offset(DATA_BUF_TYPE, *off); return sz + sizeof(int); } @@ -470,7 +476,7 @@ static __always_inline int save_str_to_buffer(bufs_t *bufs_p, void *ptr) return 0; } -static __always_inline bool prepend_path(struct path *path, bufs_t *string_p) +static __always_inline bool prepend_path(struct path *path, bufs_t *string_p, int buf_type) { char slash = '/'; char null = '\0'; @@ -519,7 +525,7 @@ static __always_inline bool prepend_path(struct path *path, bufs_t *string_p) int sz = bpf_probe_read_str(&(string_p->buf[(offset) & (MAX_STRING_SIZE - 1)]), (d_name.len + 1) & (MAX_STRING_SIZE - 1), d_name.name); if (sz > 1) { - bpf_probe_read(&(string_p->buf[(offset + d_name.len) &(MAX_STRING_SIZE - 1)]), 1, &slash); + bpf_probe_read(&(string_p->buf[(offset + d_name.len) & (MAX_STRING_SIZE - 1)]), 1, &slash); } else { offset += (d_name.len + 1); } @@ -527,7 +533,7 @@ static __always_inline bool prepend_path(struct path *path, bufs_t *string_p) dentry = parent; } - if (offset == MAX_STRING_SIZE){ + if (offset == MAX_STRING_SIZE) { return false; } @@ -535,35 +541,44 @@ static __always_inline bool prepend_path(struct path *path, bufs_t *string_p) offset--; bpf_probe_read(&(string_p->buf[offset & (MAX_STRING_SIZE - 1)]), 1, &slash); - set_buffer_offset(PATH_BUFFER, offset); + set_buffer_offset(buf_type, offset); return true; } -static __always_inline struct path* load_file_p(){ - u64 pid_tgid = bpf_get_current_pid_tgid(); - struct path *p = path_map.lookup(&pid_tgid); - path_map.delete(&pid_tgid); +static __always_inline struct path* load_file_p(int buf_type) +{ + u64 pid_tgid = bpf_get_current_pid_tgid(); + + if (buf_type == EXEC_BUF_TYPE) { + struct path *p = exec_map.lookup(&pid_tgid); + exec_map.delete(&pid_tgid); + return p; + } + + // FILE_BUF_TYPE + struct path *p = file_map.lookup(&pid_tgid); + file_map.delete(&pid_tgid); return p; } -static __always_inline int save_file_to_buffer(bufs_t *bufs_p) +static __always_inline int save_file_to_buffer(bufs_t *bufs_p, int buf_type) { - struct path *path = load_file_p(); + struct path *path = load_file_p(buf_type); - bufs_t *string_p = get_buffer(PATH_BUFFER); + bufs_t *string_p = get_buffer(buf_type); if (string_p == NULL) return -1; - if (!prepend_path(path, string_p)){ + if (!prepend_path(path, string_p, buf_type)) { return -1; } - u32 *off = get_buffer_offset(1); + u32 *off = get_buffer_offset(buf_type); if (off == NULL) return -1; - return save_str_to_buffer(bufs_p, (void *) &string_p->buf[*off]); + return save_str_to_buffer(bufs_p, (void *)&string_p->buf[*off]); } static __always_inline int save_to_buffer(bufs_t *bufs_p, void *ptr, int size, u8 type) @@ -575,11 +590,11 @@ static __always_inline int save_to_buffer(bufs_t *bufs_p, void *ptr, int size, u return 0; } - u32 *off = get_buffer_offset(DATA_BUFFER); + u32 *off = get_buffer_offset(DATA_BUF_TYPE); if (off == NULL) { return -1; } - + if (*off > MAX_BUFFER_SIZE - MAX_ELEMENT_SIZE) { return 0; } @@ -596,7 +611,7 @@ static __always_inline int save_to_buffer(bufs_t *bufs_p, void *ptr, int size, u if (bpf_probe_read(&(bufs_p->buf[*off]), size, ptr) == 0) { *off += size; - set_buffer_offset(DATA_BUFFER, *off); + set_buffer_offset(DATA_BUF_TYPE, *off); return size; } @@ -641,7 +656,7 @@ static __always_inline int save_args_to_buffer(u64 types, args_t *args) return 0; } - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) { return 0; } @@ -658,7 +673,7 @@ static __always_inline int save_args_to_buffer(u64 types, args_t *args) save_to_buffer(bufs_p, (void*)&(args->args[i]), sizeof(int), OPEN_FLAGS_T); break; case FILE_TYPE_T: - if (!save_file_to_buffer(bufs_p)) + if (!save_file_to_buffer(bufs_p, FILE_BUF_TYPE)) break; case STR_T: save_str_to_buffer(bufs_p, (void *)args->args[i]); @@ -696,11 +711,11 @@ static __always_inline int save_args_to_buffer(u64 types, args_t *args) static __always_inline int events_perf_submit(struct pt_regs *ctx) { - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return -1; - u32 *off = get_buffer_offset(DATA_BUFFER); + u32 *off = get_buffer_offset(DATA_BUF_TYPE); if (off == NULL) return -1; @@ -710,6 +725,72 @@ static __always_inline int events_perf_submit(struct pt_regs *ctx) return sys_events.perf_submit(ctx, data, size); } +// == Full Path == // + +int trace_security_bprm_check(struct pt_regs *ctx, struct linux_binprm *bprm) +{ + sys_context_t context = {}; + + if (skip_syscall()) + return 0; + + // + + struct file *f = bprm->file; + if (f == NULL) + return 0; + + struct path p; + bpf_probe_read(&p, sizeof(struct path), &f->f_path); + + bufs_t *string_p = get_buffer(EXEC_BUF_TYPE); + if (string_p == NULL) + return -1; + + if (!prepend_path(&p, string_p, EXEC_BUF_TYPE)) { + return -1; + } + + u32 *off = get_buffer_offset(EXEC_BUF_TYPE); + if (off == NULL) + return -1; + + // + + init_context(&context); + + context.event_id = _SECURITY_BPRM_CHECK; + context.argnum = 1; + context.retval = 0; + + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); + + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); + if (bufs_p == NULL) + return 0; + + save_context_to_buffer(bufs_p, (void*)&context); + save_str_to_buffer(bufs_p, (void *)&string_p->buf[*off]); + + events_perf_submit(ctx); + + return 0; +} + +int trace_security_file_open(struct pt_regs *ctx, struct file *file) +{ + if (skip_syscall()) + return 0; + + struct path p; + bpf_probe_read(&p, sizeof(struct path), &file->f_path); + + u64 tgid = bpf_get_current_pid_tgid(); + file_map.update(&tgid, &p); + + return 0; +} + // == Syscall Hooks (Process) == // int syscall__execve(struct pt_regs *ctx, @@ -728,9 +809,9 @@ int syscall__execve(struct pt_regs *ctx, context.argnum = 2; context.retval = 0; - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -762,9 +843,9 @@ int trace_ret_execve(struct pt_regs *ctx) return 0; } - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -793,9 +874,9 @@ int syscall__execveat(struct pt_regs *ctx, context.argnum = 4; context.retval = 0; - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -829,9 +910,9 @@ int trace_ret_execveat(struct pt_regs *ctx) return 0; } - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -857,9 +938,9 @@ int trace_do_exit(struct pt_regs *ctx, long code) remove_pid_ns(); - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -961,9 +1042,9 @@ static __always_inline int trace_ret_generic(u32 id, struct pt_regs *ctx, u64 ty return 0; } - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; @@ -1001,25 +1082,6 @@ int trace_ret_openat(struct pt_regs *ctx) return trace_ret_generic(_SYS_OPENAT, ctx, ARG_TYPE0(INT_T)|ARG_TYPE1(FILE_TYPE_T)|ARG_TYPE2(OPEN_FLAGS_T)); } -int kretprobe_do_filp_open(struct pt_regs *ctx) -{ - if (skip_syscall()) - return 0; - - struct file *f = (struct file *) PT_REGS_RC(ctx); - if (f == NULL){ - return -1; - } - - struct path p; - bpf_probe_read(&p, sizeof(struct path), &f->f_path); - - u64 tgid = bpf_get_current_pid_tgid(); - path_map.update(&tgid, &p); - - return 0; -} - int syscall__close(struct pt_regs *ctx) { if (skip_syscall()) @@ -1061,9 +1123,9 @@ TRACEPOINT_PROBE(syscalls, sys_exit_openat) return 0; } - set_buffer_offset(DATA_BUFFER, sizeof(sys_context_t)); + set_buffer_offset(DATA_BUF_TYPE, sizeof(sys_context_t)); - bufs_t *bufs_p = get_buffer(DATA_BUFFER); + bufs_t *bufs_p = get_buffer(DATA_BUF_TYPE); if (bufs_p == NULL) return 0; diff --git a/KubeArmor/core/containerdHandler.go b/KubeArmor/core/containerdHandler.go index 75cb21da1a..21e04bccff 100644 --- a/KubeArmor/core/containerdHandler.go +++ b/KubeArmor/core/containerdHandler.go @@ -186,13 +186,13 @@ func (ch *ContainerdHandler) GetContainerInfo(ctx context.Context, containerID s pid := strconv.Itoa(int(taskRes.Processes[0].Pid)) - if data, err := kl.GetCommandOutputWithErr("readlink", []string{"/proc/" + pid + "/ns/pid"}); err == nil { + if data, err := os.Readlink("/proc/" + pid + "/ns/pid"); err == nil { if _, err := fmt.Sscanf(data, "pid:[%d]\n", &container.PidNS); err != nil { kg.Warnf("Unable to get PidNS (%s, %s, %s)", containerID, pid, err.Error()) } } - if data, err := kl.GetCommandOutputWithErr("readlink", []string{"/proc/" + pid + "/ns/mnt"}); err == nil { + if data, err := os.Readlink("/proc/" + pid + "/ns/mnt"); err == nil { if _, err := fmt.Sscanf(data, "mnt:[%d]\n", &container.MntNS); err != nil { kg.Warnf("Unable to get MntNS (%s, %s, %s)", containerID, pid, err.Error()) } diff --git a/KubeArmor/core/dockerHandler.go b/KubeArmor/core/dockerHandler.go index a3a56a9bce..fb25bf53a6 100644 --- a/KubeArmor/core/dockerHandler.go +++ b/KubeArmor/core/dockerHandler.go @@ -138,13 +138,13 @@ func (dh *DockerHandler) GetContainerInfo(containerID string) (tp.Container, err pid := strconv.Itoa(inspect.State.Pid) - if data, err := kl.GetCommandOutputWithErr("readlink", []string{"/proc/" + pid + "/ns/pid"}); err == nil { + if data, err := os.Readlink("/proc/" + pid + "/ns/pid"); err == nil { if _, err := fmt.Sscanf(data, "pid:[%d]\n", &container.PidNS); err != nil { kg.Warnf("Unable to get PidNS (%s, %s, %s)", containerID, pid, err.Error()) } } - if data, err := kl.GetCommandOutputWithErr("readlink", []string{"/proc/" + pid + "/ns/mnt"}); err == nil { + if data, err := os.Readlink("/proc/" + pid + "/ns/mnt"); err == nil { if _, err := fmt.Sscanf(data, "mnt:[%d]\n", &container.MntNS); err != nil { kg.Warnf("Unable to get MntNS (%s, %s, %s)", containerID, pid, err.Error()) } diff --git a/KubeArmor/feeder/feeder.go b/KubeArmor/feeder/feeder.go index ed78ccdcd8..dfc0419248 100644 --- a/KubeArmor/feeder/feeder.go +++ b/KubeArmor/feeder/feeder.go @@ -556,6 +556,9 @@ func (fd *Feeder) PushLog(log tp.Log) { pbAlert.PID = log.PID pbAlert.UID = log.UID + pbAlert.ParentProcessName = log.ParentProcessName + pbAlert.ProcessName = log.ProcessName + if len(log.PolicyName) > 0 { pbAlert.PolicyName = log.PolicyName } @@ -613,6 +616,9 @@ func (fd *Feeder) PushLog(log tp.Log) { pbLog.PID = log.PID pbLog.UID = log.UID + pbLog.ParentProcessName = log.ParentProcessName + pbLog.ProcessName = log.ProcessName + pbLog.Type = log.Type pbLog.Source = log.Source pbLog.Operation = log.Operation @@ -624,8 +630,8 @@ func (fd *Feeder) PushLog(log tp.Log) { pbLog.Result = log.Result - // LogLock.Lock() - // defer LogLock.Unlock() + // LogLock.Lock() + // defer LogLock.Unlock() for uid := range LogStructs { LogStructs[uid].Broadcast <- &pbLog diff --git a/KubeArmor/monitor/hostProcessTree.go b/KubeArmor/monitor/hostProcessTree.go deleted file mode 100644 index f5baffa3c0..0000000000 --- a/KubeArmor/monitor/hostProcessTree.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2021 Authors of KubeArmor - -package monitor - -import ( - "time" - - tp "github.com/kubearmor/KubeArmor/KubeArmor/types" -) - -// ================== // -// == Process Tree == // -// ================== // - -// AddActiveHostPid Function -func (mon *SystemMonitor) AddActiveHostPid(hostPid uint32, node tp.PidNode) { - ActiveHostMap := *(mon.ActiveHostMap) - ActiveHostMapLock := *(mon.ActiveHostMapLock) - - ActiveHostMapLock.Lock() - defer ActiveHostMapLock.Unlock() - - // add pid node to ActiveHostMap - if pidMap, ok := ActiveHostMap[hostPid]; ok { - pidMap[hostPid] = node - } else { - newPidMap := tp.PidMap{node.HostPID: node} - ActiveHostMap[hostPid] = newPidMap - } -} - -// GetHostExecPath Function -func (mon *SystemMonitor) GetHostExecPath(hostPid uint32) string { - ActiveHostMap := *(mon.ActiveHostMap) - ActiveHostMapLock := *(mon.ActiveHostMapLock) - - ActiveHostMapLock.RLock() - defer ActiveHostMapLock.RUnlock() - - if pidMap, ok := ActiveHostMap[hostPid]; ok { - if node, ok := pidMap[hostPid]; ok { - return node.ExecPath - } - } - - return "" -} - -// DeleteActiveHostPid Function -func (mon *SystemMonitor) DeleteActiveHostPid(hostPid uint32) { - ActiveHostMap := *(mon.ActiveHostMap) - ActiveHostMapLock := *(mon.ActiveHostMapLock) - - ActiveHostMapLock.Lock() - defer ActiveHostMapLock.Unlock() - - // delete execve(at) host pid - if pidMap, ok := ActiveHostMap[hostPid]; ok { - if node, ok := pidMap[hostPid]; ok { - node.Exited = true - node.ExitedTime = time.Now() - } - } -} diff --git a/KubeArmor/monitor/logUpdate.go b/KubeArmor/monitor/logUpdate.go index 00e62b72d5..d0117ff15e 100644 --- a/KubeArmor/monitor/logUpdate.go +++ b/KubeArmor/monitor/logUpdate.go @@ -61,6 +61,7 @@ func (mon *SystemMonitor) BuildLogBase(msg ContextCombined) tp.Log { log = mon.UpdateContainerInfoByContainerID(log) } + log.HostPPID = int32(msg.ContextSys.HostPPID) log.HostPID = int32(msg.ContextSys.HostPID) log.PPID = int32(msg.ContextSys.PPID) @@ -68,15 +69,31 @@ func (mon *SystemMonitor) BuildLogBase(msg ContextCombined) tp.Log { log.UID = int32(msg.ContextSys.UID) if msg.ContextSys.EventID == SysExecve || msg.ContextSys.EventID == SysExecveAt { - log.Source = mon.GetExecPath(msg.ContainerID, msg.ContextSys.PPID) - } else { - log.Source = mon.GetExecPath(msg.ContainerID, msg.ContextSys.PID) + log.Source = mon.GetCommand(msg.ContainerID, msg.ContextSys.HostPPID) + } else { // otherwise + log.Source = mon.GetCommand(msg.ContainerID, msg.ContextSys.HostPID) } if log.Source == "" { log.Source = string(msg.ContextSys.Comm[:bytes.IndexByte(msg.ContextSys.Comm[:], 0)]) } + log.ParentProcessName = mon.GetExecPath(msg.ContainerID, msg.ContextSys.HostPPID) + log.ProcessName = mon.GetExecPath(msg.ContainerID, msg.ContextSys.HostPID) + + return log +} + +// UpdateLogBase Function (SYS_EXECVE, SYS_EXECVEAT) +func (mon *SystemMonitor) UpdateLogBase(eventID int32, log tp.Log) tp.Log { + source := mon.GetCommand(log.ContainerID, uint32(log.HostPPID)) + if source != "" { + log.Source = source + } + + log.ParentProcessName = mon.GetExecPath(log.ContainerID, uint32(log.HostPPID)) + log.ProcessName = mon.GetExecPath(log.ContainerID, uint32(log.HostPID)) + return log } diff --git a/KubeArmor/monitor/processTree.go b/KubeArmor/monitor/processTree.go index 37dc5cfef8..38afe39cb9 100644 --- a/KubeArmor/monitor/processTree.go +++ b/KubeArmor/monitor/processTree.go @@ -4,6 +4,8 @@ package monitor import ( + "os" + "strconv" "time" tp "github.com/kubearmor/KubeArmor/KubeArmor/types" @@ -71,14 +73,16 @@ func (mon *SystemMonitor) BuildPidNode(ctx SyscallContext, execPath string, args node.PID = ctx.PID node.UID = ctx.UID - node.Comm = string(ctx.Comm[:]) node.ExecPath = execPath + node.Args = "" for idx, arg := range args { if idx == 0 { continue + } else if idx == 1 { + node.Args = arg } else { - node.ExecPath = node.ExecPath + " " + arg + node.Args = node.Args + " " + arg } } @@ -89,22 +93,12 @@ func (mon *SystemMonitor) BuildPidNode(ctx SyscallContext, execPath string, args // AddActivePid Function func (mon *SystemMonitor) AddActivePid(containerID string, node tp.PidNode) { - ActivePidMap := *(mon.ActivePidMap) + ActiveHostPidMap := *(mon.ActiveHostPidMap) ActivePidMapLock := *(mon.ActivePidMapLock) ActivePidMapLock.Lock() defer ActivePidMapLock.Unlock() - // add pid node to ActivePidMap - if pidMap, ok := ActivePidMap[containerID]; ok { - pidMap[node.PID] = node - } else { - newPidMap := tp.PidMap{node.PID: node} - ActivePidMap[containerID] = newPidMap - } - - ActiveHostPidMap := *(mon.ActiveHostPidMap) - // add pid node to ActiveHostPidMap if pidMap, ok := ActiveHostPidMap[containerID]; ok { pidMap[node.HostPID] = node @@ -114,37 +108,86 @@ func (mon *SystemMonitor) AddActivePid(containerID string, node tp.PidNode) { } } +// UpdateExecPath Function +func (mon *SystemMonitor) UpdateExecPath(containerID string, hostPid uint32, execPath string) { + ActiveHostPidMap := *(mon.ActiveHostPidMap) + ActivePidMapLock := *(mon.ActivePidMapLock) + + ActivePidMapLock.Lock() + defer ActivePidMapLock.Unlock() + + if pidMap, ok := ActiveHostPidMap[containerID]; ok { + if node, ok := pidMap[hostPid]; ok { + newNode := node + newNode.ExecPath = execPath + ActiveHostPidMap[containerID][hostPid] = newNode + } + } +} + // GetExecPath Function -func (mon *SystemMonitor) GetExecPath(containerID string, pid uint32) string { - ActivePidMap := *(mon.ActivePidMap) +func (mon *SystemMonitor) GetExecPath(containerID string, hostPid uint32) string { + ActiveHostPidMap := *(mon.ActiveHostPidMap) ActivePidMapLock := *(mon.ActivePidMapLock) ActivePidMapLock.RLock() defer ActivePidMapLock.RUnlock() - if pidMap, ok := ActivePidMap[containerID]; ok { - if node, ok := pidMap[pid]; ok { + // container side + if pidMap, ok := ActiveHostPidMap[containerID]; ok { + if node, ok := pidMap[hostPid]; ok { return node.ExecPath } } + // host side or between host and container + if pidMap, ok := ActiveHostPidMap[""]; ok { + if node, ok := pidMap[hostPid]; ok { + return node.ExecPath + } + } + + // just in case that it couldn't still get the full path + if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(hostPid), 10) + "/exe"); err == nil && data != "" { + return data + } + return "" } -// GetExecPathWithHostPID Function -func (mon *SystemMonitor) GetExecPathWithHostPID(containerID string, hostPid uint32) string { +// GetCommand Function +func (mon *SystemMonitor) GetCommand(containerID string, hostPid uint32) string { ActiveHostPidMap := *(mon.ActiveHostPidMap) ActivePidMapLock := *(mon.ActivePidMapLock) ActivePidMapLock.RLock() defer ActivePidMapLock.RUnlock() + // container side if pidMap, ok := ActiveHostPidMap[containerID]; ok { if node, ok := pidMap[hostPid]; ok { + if node.Args != "" { + return node.ExecPath + " " + node.Args + } return node.ExecPath } } + // host side or between host and container + if pidMap, ok := ActiveHostPidMap[containerID]; ok { + if node, ok := pidMap[hostPid]; ok { + if node.Args != "" { + return node.ExecPath + " " + node.Args + } + return node.ExecPath + } + } + + // just in case that it couldn't still get the full path + if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(hostPid), 10) + "/exe"); err == nil && data != "" { + return data + } + return "" } @@ -152,22 +195,12 @@ func (mon *SystemMonitor) GetExecPathWithHostPID(containerID string, hostPid uin func (mon *SystemMonitor) DeleteActivePid(containerID string, ctx SyscallContext) { now := time.Now() - ActivePidMap := *(mon.ActivePidMap) + ActiveHostPidMap := *(mon.ActiveHostPidMap) ActivePidMapLock := *(mon.ActivePidMapLock) ActivePidMapLock.Lock() defer ActivePidMapLock.Unlock() - // delete execve(at) pid - if pidMap, ok := ActivePidMap[containerID]; ok { - if node, ok := pidMap[ctx.PID]; ok { - node.Exited = true - node.ExitedTime = now - } - } - - ActiveHostPidMap := *(mon.ActiveHostPidMap) - // delete execve(at) host pid if pidMap, ok := ActiveHostPidMap[containerID]; ok { if node, ok := pidMap[ctx.HostPID]; ok { @@ -182,26 +215,18 @@ func (mon *SystemMonitor) CleanUpExitedHostPids() { for range mon.Ticker.C { now := time.Now() - ActivePidMap := *(mon.ActivePidMap) + ActiveHostPidMap := *(mon.ActiveHostPidMap) ActivePidMapLock := *(mon.ActivePidMapLock) ActivePidMapLock.Lock() - for _, pidMap := range ActivePidMap { + for _, pidMap := range ActiveHostPidMap { for pid, pidNode := range pidMap { if pidNode.Exited { - if now.After(pidNode.ExitedTime.Add(time.Second * 5)) { - delete(pidMap, pid) + if _, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(pidNode.HostPID), 10) + "/exe"); err == nil { + continue } - } - } - } - - ActiveHostPidMap := *(mon.ActiveHostPidMap) - for _, pidMap := range ActiveHostPidMap { - for pid, pidNode := range pidMap { - if pidNode.Exited { if now.After(pidNode.ExitedTime.Add(time.Second * 5)) { delete(pidMap, pid) } @@ -210,22 +235,5 @@ func (mon *SystemMonitor) CleanUpExitedHostPids() { } ActivePidMapLock.Unlock() - - ActiveHostMap := *(mon.ActiveHostMap) - ActiveHostMapLock := *(mon.ActiveHostMapLock) - - ActiveHostMapLock.Lock() - - for _, pidMap := range ActiveHostMap { - for pid, pidNode := range pidMap { - if pidNode.Exited { - if now.After(pidNode.ExitedTime.Add(time.Second * 10)) { - delete(pidMap, pid) - } - } - } - } - - ActiveHostMapLock.Unlock() } } diff --git a/KubeArmor/monitor/syscallParser.go b/KubeArmor/monitor/syscallParser.go index 2e98c7c524..f315df0f25 100644 --- a/KubeArmor/monitor/syscallParser.go +++ b/KubeArmor/monitor/syscallParser.go @@ -775,7 +775,7 @@ func getSyscallName(sc int32) string { 332: "SYS_STATX", 351: "DO_EXIT", - 352: "CAP_CAPABLE", + 352: "SECURITY_BPRM_CHECK", } var res string diff --git a/KubeArmor/monitor/systemMonitor.go b/KubeArmor/monitor/systemMonitor.go index 7b4293c67e..74237fd374 100644 --- a/KubeArmor/monitor/systemMonitor.go +++ b/KubeArmor/monitor/systemMonitor.go @@ -42,7 +42,9 @@ const ( SysExecve = 59 SysExecveAt = 322 - DoExit = 351 + + DoExit = 351 + SecurityBprmCheck = 352 ) // SystemMonitor Constant Values @@ -118,8 +120,7 @@ type SystemMonitor struct { Containers *map[string]tp.Container ContainersLock **sync.RWMutex - // container id -> (host) pid - ActivePidMap *map[string]tp.PidMap + // container id -> host pid ActiveHostPidMap *map[string]tp.PidMap ActivePidMapLock **sync.RWMutex @@ -138,10 +139,6 @@ type SystemMonitor struct { SyscallLostChannel chan uint64 SyscallPerfMap *bcc.PerfMap - // host pid - ActiveHostMap *map[uint32]tp.PidMap - ActiveHostMapLock **sync.RWMutex - // system monitor (for host) HostBpfModule *bcc.Module @@ -180,13 +177,9 @@ func NewSystemMonitor(node tp.Node, logger *fd.Feeder, containers *map[string]tp mon.Containers = containers mon.ContainersLock = containersLock - mon.ActivePidMap = activePidMap mon.ActiveHostPidMap = activeHostPidMap mon.ActivePidMapLock = activePidMapLock - mon.ActiveHostMap = activeHostMap - mon.ActiveHostMapLock = activeHostMapLock - mon.NsMap = make(map[NsKey]string) mon.NsMapLock = new(sync.RWMutex) @@ -198,7 +191,7 @@ func NewSystemMonitor(node tp.Node, logger *fd.Feeder, containers *map[string]tp mon.UptimeTimeStamp = kl.GetUptimeTimestamp() mon.HostByteOrder = bcc.GetHostByteOrder() - mon.Ticker = time.NewTicker(time.Second * 1) + mon.Ticker = time.NewTicker(time.Second * 10) mon.IsCOS = false @@ -325,25 +318,16 @@ func (mon *SystemMonitor) InitBPF() error { } } - kretp, err := mon.BpfModule.LoadKprobe("kretprobe_do_filp_open") - if err != nil { - return fmt.Errorf("error loading kprobe %s", "kretprobe_do_filp_open") - } - err = mon.BpfModule.AttachKretprobe("do_filp_open", kretp, -1) - if err != nil { - return fmt.Errorf("error attaching kprobe") - } + sysKprobes := []string{"do_exit", "security_bprm_check", "security_file_open"} - tracepoints := []string{"do_exit"} - - for _, tracepoint := range tracepoints { - kp, err := mon.BpfModule.LoadKprobe(fmt.Sprintf("trace_%s", tracepoint)) + for _, sysKprobe := range sysKprobes { + kp, err := mon.BpfModule.LoadKprobe(fmt.Sprintf("trace_%s", sysKprobe)) if err != nil { - return fmt.Errorf("error loading kprobe %s: %v", tracepoint, err) + return fmt.Errorf("error loading kprobe %s: %v", sysKprobe, err) } - err = mon.BpfModule.AttachKprobe(tracepoint, kp, -1) + err = mon.BpfModule.AttachKprobe(sysKprobe, kp, -1) if err != nil { - return fmt.Errorf("error attaching kprobe %s: %v", tracepoint, err) + return fmt.Errorf("error attaching kprobe %s: %v", sysKprobe, err) } } @@ -391,25 +375,16 @@ func (mon *SystemMonitor) InitBPF() error { } } - kretp, err := mon.HostBpfModule.LoadKprobe("kretprobe_do_filp_open") - if err != nil { - return fmt.Errorf("error loading kprobe %s", "kretprobe_do_filp_open") - } - err = mon.HostBpfModule.AttachKretprobe("do_filp_open", kretp, -1) - if err != nil { - return fmt.Errorf("error attaching kprobe") - } - - tracepoints := []string{"do_exit"} + sysKprobes := []string{"do_exit", "security_bprm_check", "security_file_open"} - for _, tracepoint := range tracepoints { - kp, err := mon.HostBpfModule.LoadKprobe(fmt.Sprintf("trace_%s", tracepoint)) + for _, sysKprobe := range sysKprobes { + kp, err := mon.HostBpfModule.LoadKprobe(fmt.Sprintf("trace_%s", sysKprobe)) if err != nil { - return fmt.Errorf("error loading kprobe %s: %v", tracepoint, err) + return fmt.Errorf("error loading kprobe %s: %v", sysKprobe, err) } - err = mon.HostBpfModule.AttachKprobe(tracepoint, kp, -1) + err = mon.HostBpfModule.AttachKprobe(sysKprobe, kp, -1) if err != nil { - return fmt.Errorf("error attaching kprobe %s: %v", tracepoint, err) + return fmt.Errorf("error attaching kprobe %s: %v", sysKprobe, err) } } @@ -559,6 +534,11 @@ func (mon *SystemMonitor) TraceSyscall() { // remove the log from the map delete(execLogMap, ctx.HostPID) + // update the log again + if !strings.HasPrefix(log.Source, "/") { + log = mon.UpdateLogBase(ctx.EventID, log) + } + // get error message if ctx.Retval < 0 { message := getErrorMessage(ctx.Retval) @@ -623,6 +603,11 @@ func (mon *SystemMonitor) TraceSyscall() { // remove the log from the map delete(execLogMap, ctx.HostPID) + // update the log again + if !strings.HasPrefix(log.Source, "/") { + log = mon.UpdateLogBase(ctx.EventID, log) + } + // get error message if ctx.Retval < 0 { message := getErrorMessage(ctx.Retval) @@ -645,6 +630,11 @@ func (mon *SystemMonitor) TraceSyscall() { } else if ctx.EventID == DoExit { mon.DeleteActivePid(containerID, ctx) continue + } else if ctx.EventID == SecurityBprmCheck { + if val, ok := args[0].(string); ok { + mon.UpdateExecPath(containerID, ctx.HostPID, val) + } + continue } // push the context to the channel for logging @@ -699,7 +689,7 @@ func (mon *SystemMonitor) TraceHostSyscall() { if len(args) == 2 { // enter // build a pid node pidNode := mon.BuildPidNode(ctx, args[0].(string), args[1].([]string)) - mon.AddActiveHostPid(ctx.HostPID, pidNode) + mon.AddActivePid("", pidNode) // generate a log with the base information log := mon.BuildLogBase(ContextCombined{ContainerID: "", ContextSys: ctx}) @@ -731,6 +721,11 @@ func (mon *SystemMonitor) TraceHostSyscall() { // remove the log from the map delete(execLogMap, ctx.HostPID) + // update the log again + if !strings.HasPrefix(log.Source, "/") { + log = mon.UpdateLogBase(ctx.EventID, log) + } + // get error message if ctx.Retval < 0 { message := getErrorMessage(ctx.Retval) @@ -754,7 +749,7 @@ func (mon *SystemMonitor) TraceHostSyscall() { if len(args) == 4 { // enter // build a pid node pidNode := mon.BuildPidNode(ctx, args[1].(string), args[2].([]string)) - mon.AddActiveHostPid(ctx.HostPID, pidNode) + mon.AddActivePid("", pidNode) // generate a log with the base information log := mon.BuildLogBase(ContextCombined{ContainerID: "", ContextSys: ctx}) @@ -795,6 +790,11 @@ func (mon *SystemMonitor) TraceHostSyscall() { // remove the log from the map delete(execLogMap, ctx.HostPID) + // update the log again + if !strings.HasPrefix(log.Source, "/") { + log = mon.UpdateLogBase(ctx.EventID, log) + } + // get error message if ctx.Retval < 0 { message := getErrorMessage(ctx.Retval) @@ -815,7 +815,12 @@ func (mon *SystemMonitor) TraceHostSyscall() { continue } else if ctx.EventID == DoExit { - mon.DeleteActiveHostPid(ctx.HostPID) + mon.DeleteActivePid("", ctx) + continue + } else if ctx.EventID == SecurityBprmCheck { + if val, ok := args[0].(string); ok { + mon.UpdateExecPath("", ctx.HostPID, val) + } continue } diff --git a/KubeArmor/types/types.go b/KubeArmor/types/types.go index 36b695fe9d..2404e1d08a 100644 --- a/KubeArmor/types/types.go +++ b/KubeArmor/types/types.go @@ -187,10 +187,15 @@ type Log struct { MergedDir string `json:"mergedDir,omitempty"` // common - HostPID int32 `json:"hostPid"` - PPID int32 `json:"ppid"` - PID int32 `json:"pid"` - UID int32 `json:"uid"` + HostPPID int32 `json:"hostPPid"` + HostPID int32 `json:"hostPid"` + PPID int32 `json:"ppid"` + PID int32 `json:"pid"` + UID int32 `json:"uid"` + + // process + ParentProcessName string `json:"parentProcessName"` + ProcessName string `json:"processName"` // policy PolicyName string `json:"policyName,omitempty"` @@ -505,8 +510,8 @@ type PidNode struct { PID uint32 UID uint32 - Comm string ExecPath string + Args string Exited bool ExitedTime time.Time diff --git a/contribution/self-managed-k8s/setup.sh b/contribution/self-managed-k8s/setup.sh index 6879d40af2..e171e482a1 100755 --- a/contribution/self-managed-k8s/setup.sh +++ b/contribution/self-managed-k8s/setup.sh @@ -16,7 +16,7 @@ sudo apt-get update sudo rm -rf /tmp/build; mkdir -p /tmp/build; cd /tmp/build # download bcc -git -C /tmp/build/ clone https://github.com/iovisor/bcc.git +git -C /tmp/build/ clone --branch v0.24.0 --depth 1 https://github.com/iovisor/bcc.git # install dependencies for bcc sudo apt-get -y install build-essential cmake bison flex git python3 python3-pip \ diff --git a/examples/host-security-policies/hsp-kubearmor-dev-next-proc-path-block.yaml b/examples/host-security-policies/hsp-kubearmor-dev-next-proc-path-block.yaml index ad47bb1bf0..ca7f3847ee 100644 --- a/examples/host-security-policies/hsp-kubearmor-dev-next-proc-path-block.yaml +++ b/examples/host-security-policies/hsp-kubearmor-dev-next-proc-path-block.yaml @@ -9,6 +9,6 @@ spec: severity: 5 process: matchPaths: - - path: /usr/bin/screen # try screen -h + - path: /usr/bin/diff # try diff -h action: Block diff --git a/examples/host-security-policies/hsp-kubearmor-dev-proc-path-block.yaml b/examples/host-security-policies/hsp-kubearmor-dev-proc-path-block.yaml index 0eb12a8363..15b14d43cf 100644 --- a/examples/host-security-policies/hsp-kubearmor-dev-proc-path-block.yaml +++ b/examples/host-security-policies/hsp-kubearmor-dev-proc-path-block.yaml @@ -9,6 +9,6 @@ spec: severity: 5 process: matchPaths: - - path: /usr/bin/screen # try screen -h + - path: /usr/bin/diff # try diff -h action: Block diff --git a/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-dir.yaml b/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-dir.yaml deleted file mode 100644 index a3025f24ef..0000000000 --- a/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-dir.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: security.kubearmor.com/v1 -kind: KubeArmorPolicy -metadata: - name: ksp-group-2-file-path-block-from-source-dir - namespace: multiubuntu -spec: - severity: 5 - message: "block /bin/* from accessing /home/user1/secret_data1.txt" - selector: - matchLabels: - group: group-2 - file: - matchPaths: - - path: /home/user1/secret_data1.txt - fromSource: - - dir: /bin/ - action: - Block diff --git a/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-path.yaml b/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-path.yaml index fc19568572..cd6da0bbe3 100644 --- a/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-path.yaml +++ b/examples/multiubuntu/security-policies/ksp-group-2-file-path-block-from-source-path.yaml @@ -13,6 +13,6 @@ spec: matchPaths: - path: /secret.txt # /bin/cat /secret.txt (permission denied) fromSource: # head /secret.txt (success) - - path: /bin/cat # + - path: /bin/cat action: Block diff --git a/examples/multiubuntu/security-policies/ksp-ubuntu-4-file-path-readonly-audit-from-source-path.yaml b/examples/multiubuntu/security-policies/ksp-ubuntu-4-file-path-readonly-audit-from-source-path.yaml index 582d2732f6..fe7ba9a81c 100644 --- a/examples/multiubuntu/security-policies/ksp-ubuntu-4-file-path-readonly-audit-from-source-path.yaml +++ b/examples/multiubuntu/security-policies/ksp-ubuntu-4-file-path-readonly-audit-from-source-path.yaml @@ -19,8 +19,8 @@ spec: - path: /bin/cat # /bin/vi /etc/passwd (logs) - path: /secret.txt # echo "test" >> /secret.txt (no logs) - path: /credentials/password # echo "test" >> /credentials/password (logs) - readOnly: true # /bin/vi /credentials/password (logs) + readOnly: true # /bin/cat /credentials/password (logs) fromSource: - - path: /bin/vi # /bin/cat /credentials/password (logs) + - path: /bin/cat # /bin/cat /credentials/password (logs) action: Audit diff --git a/examples/multiubuntu/security-policies/sep-ubuntu-3-file-allow.yaml b/examples/multiubuntu/security-policies/sep-ubuntu-3-file-allow.yaml deleted file mode 100644 index d2956a43d9..0000000000 --- a/examples/multiubuntu/security-policies/sep-ubuntu-3-file-allow.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: security.kubearmor.com/v1 -kind: KubeArmorPolicy -metadata: - name: sep-ubuntu-3-file-allow - namespace: multiubuntu -spec: - severity: 5 - selector: - matchLabels: - container: ubuntu-3 - selinux: - matchVolumeMounts: - - path: /host/var/log/firewalld - action: - Allow diff --git a/protobuf/kubearmor.pb.go b/protobuf/kubearmor.pb.go index 4007a636f8..337f265e01 100644 --- a/protobuf/kubearmor.pb.go +++ b/protobuf/kubearmor.pb.go @@ -182,30 +182,32 @@ type Alert struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timestamp int64 `protobuf:"varint,1,opt,name=Timestamp,proto3" json:"Timestamp,omitempty"` - UpdatedTime string `protobuf:"bytes,2,opt,name=UpdatedTime,proto3" json:"UpdatedTime,omitempty"` - ClusterName string `protobuf:"bytes,3,opt,name=ClusterName,proto3" json:"ClusterName,omitempty"` - HostName string `protobuf:"bytes,4,opt,name=HostName,proto3" json:"HostName,omitempty"` - NamespaceName string `protobuf:"bytes,5,opt,name=NamespaceName,proto3" json:"NamespaceName,omitempty"` - PodName string `protobuf:"bytes,6,opt,name=PodName,proto3" json:"PodName,omitempty"` - ContainerID string `protobuf:"bytes,7,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` - ContainerName string `protobuf:"bytes,8,opt,name=ContainerName,proto3" json:"ContainerName,omitempty"` - HostPID int32 `protobuf:"varint,9,opt,name=HostPID,proto3" json:"HostPID,omitempty"` - PPID int32 `protobuf:"varint,10,opt,name=PPID,proto3" json:"PPID,omitempty"` - PID int32 `protobuf:"varint,11,opt,name=PID,proto3" json:"PID,omitempty"` - UID int32 `protobuf:"varint,12,opt,name=UID,proto3" json:"UID,omitempty"` - PolicyName string `protobuf:"bytes,13,opt,name=PolicyName,proto3" json:"PolicyName,omitempty"` - Severity string `protobuf:"bytes,14,opt,name=Severity,proto3" json:"Severity,omitempty"` - Tags string `protobuf:"bytes,15,opt,name=Tags,proto3" json:"Tags,omitempty"` - Message string `protobuf:"bytes,16,opt,name=Message,proto3" json:"Message,omitempty"` - Type string `protobuf:"bytes,17,opt,name=Type,proto3" json:"Type,omitempty"` - Source string `protobuf:"bytes,18,opt,name=Source,proto3" json:"Source,omitempty"` - Operation string `protobuf:"bytes,19,opt,name=Operation,proto3" json:"Operation,omitempty"` - Resource string `protobuf:"bytes,20,opt,name=Resource,proto3" json:"Resource,omitempty"` - Data string `protobuf:"bytes,21,opt,name=Data,proto3" json:"Data,omitempty"` - Action string `protobuf:"bytes,22,opt,name=Action,proto3" json:"Action,omitempty"` - Result string `protobuf:"bytes,23,opt,name=Result,proto3" json:"Result,omitempty"` - ContainerImage string `protobuf:"bytes,24,opt,name=ContainerImage,proto3" json:"ContainerImage,omitempty"` + Timestamp int64 `protobuf:"varint,1,opt,name=Timestamp,proto3" json:"Timestamp,omitempty"` + UpdatedTime string `protobuf:"bytes,2,opt,name=UpdatedTime,proto3" json:"UpdatedTime,omitempty"` + ClusterName string `protobuf:"bytes,3,opt,name=ClusterName,proto3" json:"ClusterName,omitempty"` + HostName string `protobuf:"bytes,4,opt,name=HostName,proto3" json:"HostName,omitempty"` + NamespaceName string `protobuf:"bytes,5,opt,name=NamespaceName,proto3" json:"NamespaceName,omitempty"` + PodName string `protobuf:"bytes,6,opt,name=PodName,proto3" json:"PodName,omitempty"` + ContainerID string `protobuf:"bytes,7,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` + ContainerName string `protobuf:"bytes,8,opt,name=ContainerName,proto3" json:"ContainerName,omitempty"` + HostPID int32 `protobuf:"varint,9,opt,name=HostPID,proto3" json:"HostPID,omitempty"` + PPID int32 `protobuf:"varint,10,opt,name=PPID,proto3" json:"PPID,omitempty"` + PID int32 `protobuf:"varint,11,opt,name=PID,proto3" json:"PID,omitempty"` + UID int32 `protobuf:"varint,12,opt,name=UID,proto3" json:"UID,omitempty"` + PolicyName string `protobuf:"bytes,13,opt,name=PolicyName,proto3" json:"PolicyName,omitempty"` + Severity string `protobuf:"bytes,14,opt,name=Severity,proto3" json:"Severity,omitempty"` + Tags string `protobuf:"bytes,15,opt,name=Tags,proto3" json:"Tags,omitempty"` + Message string `protobuf:"bytes,16,opt,name=Message,proto3" json:"Message,omitempty"` + Type string `protobuf:"bytes,17,opt,name=Type,proto3" json:"Type,omitempty"` + Source string `protobuf:"bytes,18,opt,name=Source,proto3" json:"Source,omitempty"` + Operation string `protobuf:"bytes,19,opt,name=Operation,proto3" json:"Operation,omitempty"` + Resource string `protobuf:"bytes,20,opt,name=Resource,proto3" json:"Resource,omitempty"` + Data string `protobuf:"bytes,21,opt,name=Data,proto3" json:"Data,omitempty"` + Action string `protobuf:"bytes,22,opt,name=Action,proto3" json:"Action,omitempty"` + Result string `protobuf:"bytes,23,opt,name=Result,proto3" json:"Result,omitempty"` + ContainerImage string `protobuf:"bytes,24,opt,name=ContainerImage,proto3" json:"ContainerImage,omitempty"` + ParentProcessName string `protobuf:"bytes,25,opt,name=ParentProcessName,proto3" json:"ParentProcessName,omitempty"` + ProcessName string `protobuf:"bytes,26,opt,name=ProcessName,proto3" json:"ProcessName,omitempty"` } func (x *Alert) Reset() { @@ -408,31 +410,47 @@ func (x *Alert) GetContainerImage() string { return "" } +func (x *Alert) GetParentProcessName() string { + if x != nil { + return x.ParentProcessName + } + return "" +} + +func (x *Alert) GetProcessName() string { + if x != nil { + return x.ProcessName + } + return "" +} + // log struct type Log struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Timestamp int64 `protobuf:"varint,1,opt,name=Timestamp,proto3" json:"Timestamp,omitempty"` - UpdatedTime string `protobuf:"bytes,2,opt,name=UpdatedTime,proto3" json:"UpdatedTime,omitempty"` - ClusterName string `protobuf:"bytes,3,opt,name=ClusterName,proto3" json:"ClusterName,omitempty"` - HostName string `protobuf:"bytes,4,opt,name=HostName,proto3" json:"HostName,omitempty"` - NamespaceName string `protobuf:"bytes,5,opt,name=NamespaceName,proto3" json:"NamespaceName,omitempty"` - PodName string `protobuf:"bytes,6,opt,name=PodName,proto3" json:"PodName,omitempty"` - ContainerID string `protobuf:"bytes,7,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` - ContainerName string `protobuf:"bytes,8,opt,name=ContainerName,proto3" json:"ContainerName,omitempty"` - HostPID int32 `protobuf:"varint,9,opt,name=HostPID,proto3" json:"HostPID,omitempty"` - PPID int32 `protobuf:"varint,10,opt,name=PPID,proto3" json:"PPID,omitempty"` - PID int32 `protobuf:"varint,11,opt,name=PID,proto3" json:"PID,omitempty"` - UID int32 `protobuf:"varint,12,opt,name=UID,proto3" json:"UID,omitempty"` - Type string `protobuf:"bytes,13,opt,name=Type,proto3" json:"Type,omitempty"` - Source string `protobuf:"bytes,14,opt,name=Source,proto3" json:"Source,omitempty"` - Operation string `protobuf:"bytes,15,opt,name=Operation,proto3" json:"Operation,omitempty"` - Resource string `protobuf:"bytes,16,opt,name=Resource,proto3" json:"Resource,omitempty"` - Data string `protobuf:"bytes,17,opt,name=Data,proto3" json:"Data,omitempty"` - Result string `protobuf:"bytes,18,opt,name=Result,proto3" json:"Result,omitempty"` - ContainerImage string `protobuf:"bytes,19,opt,name=ContainerImage,proto3" json:"ContainerImage,omitempty"` + Timestamp int64 `protobuf:"varint,1,opt,name=Timestamp,proto3" json:"Timestamp,omitempty"` + UpdatedTime string `protobuf:"bytes,2,opt,name=UpdatedTime,proto3" json:"UpdatedTime,omitempty"` + ClusterName string `protobuf:"bytes,3,opt,name=ClusterName,proto3" json:"ClusterName,omitempty"` + HostName string `protobuf:"bytes,4,opt,name=HostName,proto3" json:"HostName,omitempty"` + NamespaceName string `protobuf:"bytes,5,opt,name=NamespaceName,proto3" json:"NamespaceName,omitempty"` + PodName string `protobuf:"bytes,6,opt,name=PodName,proto3" json:"PodName,omitempty"` + ContainerID string `protobuf:"bytes,7,opt,name=ContainerID,proto3" json:"ContainerID,omitempty"` + ContainerName string `protobuf:"bytes,8,opt,name=ContainerName,proto3" json:"ContainerName,omitempty"` + HostPID int32 `protobuf:"varint,9,opt,name=HostPID,proto3" json:"HostPID,omitempty"` + PPID int32 `protobuf:"varint,10,opt,name=PPID,proto3" json:"PPID,omitempty"` + PID int32 `protobuf:"varint,11,opt,name=PID,proto3" json:"PID,omitempty"` + UID int32 `protobuf:"varint,12,opt,name=UID,proto3" json:"UID,omitempty"` + Type string `protobuf:"bytes,13,opt,name=Type,proto3" json:"Type,omitempty"` + Source string `protobuf:"bytes,14,opt,name=Source,proto3" json:"Source,omitempty"` + Operation string `protobuf:"bytes,15,opt,name=Operation,proto3" json:"Operation,omitempty"` + Resource string `protobuf:"bytes,16,opt,name=Resource,proto3" json:"Resource,omitempty"` + Data string `protobuf:"bytes,17,opt,name=Data,proto3" json:"Data,omitempty"` + Result string `protobuf:"bytes,18,opt,name=Result,proto3" json:"Result,omitempty"` + ContainerImage string `protobuf:"bytes,19,opt,name=ContainerImage,proto3" json:"ContainerImage,omitempty"` + ParentProcessName string `protobuf:"bytes,20,opt,name=ParentProcessName,proto3" json:"ParentProcessName,omitempty"` + ProcessName string `protobuf:"bytes,21,opt,name=ProcessName,proto3" json:"ProcessName,omitempty"` } func (x *Log) Reset() { @@ -600,6 +618,20 @@ func (x *Log) GetContainerImage() string { return "" } +func (x *Log) GetParentProcessName() string { + if x != nil { + return x.ParentProcessName + } + return "" +} + +func (x *Log) GetProcessName() string { + if x != nil { + return x.ProcessName + } + return "" +} + // request message type RequestMessage struct { state protoimpl.MessageState @@ -717,7 +749,7 @@ var file_kubearmor_proto_rawDesc = []byte{ 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9b, 0x05, 0x0a, 0x05, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xeb, 0x05, 0x0a, 0x05, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, @@ -759,7 +791,12 @@ var file_kubearmor_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x22, 0x97, 0x04, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x54, + 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, + 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, + 0x61, 0x6d, 0x65, 0x22, 0xe7, 0x04, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, @@ -792,7 +829,12 @@ var file_kubearmor_proto_rawDesc = []byte{ 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, + 0x11, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x28, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x26, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6c, 0x79, diff --git a/protobuf/kubearmor.proto b/protobuf/kubearmor.proto index 6b0e837d5d..9eea9332ec 100644 --- a/protobuf/kubearmor.proto +++ b/protobuf/kubearmor.proto @@ -59,6 +59,9 @@ message Alert { string Result = 23; string ContainerImage = 24; + + string ParentProcessName = 25; + string ProcessName = 26; } // log struct @@ -89,6 +92,9 @@ message Log { string Result = 18; string ContainerImage = 19; + + string ParentProcessName = 20; + string ProcessName = 21; } // request message diff --git a/tests/host_scenarios/kubearmor-dev-next_test_1/cmd1 b/tests/host_scenarios/kubearmor-dev-next_test_1/cmd1 index e6c24d37c7..fb28d0e1e6 100644 --- a/tests/host_scenarios/kubearmor-dev-next_test_1/cmd1 +++ b/tests/host_scenarios/kubearmor-dev-next_test_1/cmd1 @@ -1,7 +1,7 @@ source: kubearmor-dev-next -cmd: screen -h +cmd: diff -h result: failed --- operation: Process -condition: screen -action: Block \ No newline at end of file +condition: diff +action: Block diff --git a/tests/host_scenarios/kubearmor-dev-next_test_2/cmd1 b/tests/host_scenarios/kubearmor-dev-next_test_2/cmd1 index 94f9fdaa91..8bd63e98fc 100644 --- a/tests/host_scenarios/kubearmor-dev-next_test_2/cmd1 +++ b/tests/host_scenarios/kubearmor-dev-next_test_2/cmd1 @@ -4,4 +4,4 @@ result: passed --- operation: File condition: passwd -action: Audit \ No newline at end of file +action: Audit diff --git a/tests/host_scenarios/kubearmor-dev_test_1/cmd1 b/tests/host_scenarios/kubearmor-dev_test_1/cmd1 index e517e92ad4..0645e9df78 100644 --- a/tests/host_scenarios/kubearmor-dev_test_1/cmd1 +++ b/tests/host_scenarios/kubearmor-dev_test_1/cmd1 @@ -1,7 +1,7 @@ source: kubearmor-dev -cmd: screen -h +cmd: diff -h result: failed --- operation: Process -condition: screen -action: Block \ No newline at end of file +condition: diff +action: Block diff --git a/tests/host_scenarios/kubearmor-dev_test_2/cmd1 b/tests/host_scenarios/kubearmor-dev_test_2/cmd1 index 4e6489cda2..36748e0680 100644 --- a/tests/host_scenarios/kubearmor-dev_test_2/cmd1 +++ b/tests/host_scenarios/kubearmor-dev_test_2/cmd1 @@ -4,4 +4,4 @@ result: passed --- operation: File condition: passwd -action: Audit \ No newline at end of file +action: Audit diff --git a/tests/test-scenarios-github.sh b/tests/test-scenarios-github.sh index b49a608ec0..00f512bd37 100755 --- a/tests/test-scenarios-github.sh +++ b/tests/test-scenarios-github.sh @@ -144,8 +144,8 @@ function start_and_wait_for_kubearmor_initialization() { CAT_LOG="cat $ARMOR_LOG" CAT_MSG="cat $ARMOR_MSG" - PROXY=$(ps -ef | grep "kubectl proxy" | wc -l) - if [ $PROXY != 2 ]; then + PROXY=$(sudo netstat -ntlp | grep kubectl | grep 8001 | wc -l) + if [ $PROXY != 1 ]; then FAIL "Proxy is not running" exit 1 fi diff --git a/tests/test-scenarios-local.sh b/tests/test-scenarios-local.sh index 3e7d7e62b0..8643762c10 100755 --- a/tests/test-scenarios-local.sh +++ b/tests/test-scenarios-local.sh @@ -109,8 +109,8 @@ function start_and_wait_for_kubearmor_initialization() { exit 1 fi - PROXY=$(ps -ef | grep "kubectl proxy" | wc -l) - if [ $PROXY != 2 ]; then + PROXY=$(sudo netstat -ntlp | grep kubectl | grep 8001 | wc -l) + if [ $PROXY != 1 ]; then FAIL "Proxy is not running" exit 1 fi