From fdeb11b894f5629c908f4c5ad9767682693b53d0 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Fri, 3 Nov 2023 00:33:33 +0100 Subject: [PATCH 1/3] policylibrary: add a catch all for setuid root Signed-off-by: Djalal Harouni --- .../privileges/privileges-setuid-root.yaml | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 examples/policylibrary/privileges/privileges-setuid-root.yaml diff --git a/examples/policylibrary/privileges/privileges-setuid-root.yaml b/examples/policylibrary/privileges/privileges-setuid-root.yaml new file mode 100644 index 00000000000..d66aad740a6 --- /dev/null +++ b/examples/policylibrary/privileges/privileges-setuid-root.yaml @@ -0,0 +1,246 @@ +# This 'privileges-setuid-root' Tracing Policy monitors processes trying +# to change their uids/gids to user root. +# +# __sys_setuid +# - __x64_sys_setuid +# - __ia32_sys_setuid +# - __x64_sys_setuid16 +# - __ia32_sys_setuid16 +# +# __sys_setgid +# - __x64_sys_setgid +# - __ia32_sys_setgid +# - __x64_sys_setgid16 +# - __ia32_sys_setgid16 +# +# __sys_setreuid +# - __x64_sys_setreuid +# - __ia32_sys_setreuid +# - __x64_sys_setreuid16 +# - __ia32_sys_setreuid16 +# +# __sys_setregid +# - __x64_sys_setregid +# - __ia32_sys_setregid +# - __x64_sys_setregid16 +# - __ia32_sys_setregid16 +# +# __sys_setresuid +# - __x64_sys_setresuid +# - __ia32_sys_setresuid +# - __x64_sys_setresuid16 +# - __ia32_sys_setresuid16 +# +# __sys_setresgid +# - __x64_sys_setresgid +# - __ia32_sys_setresgid +# - __x64_sys_setresgid16 +# - __ia32_sys_setresgid16 +# +# __sys_setfsuid +# - __x64_sys_setfsuid +# - __ia32_sys_setfsuid +# - __x64_sys_setfsuid16 +# - __ia32_sys_setfsuid16 +# +# __sys_setfsgid +# - __x64_sys_setfsgid +# - __ia32_sys_setfsgid +# - __x64_sys_setfsgid16 +# - __ia32_sys_setfsgid16 +# + +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "privileges-setuid-root.yaml" +spec: + kprobes: + - call: "__sys_setuid" + syscall: false + return: true + args: + - index: 0 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setgid" + syscall: false + return: true + args: + - index: 0 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setreuid" + syscall: false + return: true + args: + - index: 0 + type: "int" + - index: 1 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - matchArgs: + - index: 1 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setregid" + syscall: false + return: true + args: + - index: 0 + type: "int" + - index: 1 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - matchArgs: + - index: 1 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setresuid" + syscall: false + return: true + args: + - index: 0 + type: "int" + - index: 1 + type: "int" + - index: 2 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 1 # We care about the effective user id to reduce noise + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - matchArgs: + - index: 2 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setresgid" + syscall: false + return: true + args: + - index: 0 + type: "int" + - index: 1 + type: "int" + - index: 2 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 1 # We care about the effective group id to reduce noise + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - matchArgs: + - index: 2 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setfsuid" + syscall: false + return: true + args: + - index: 0 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min + - call: "__sys_setfsgid" + syscall: false + return: true + args: + - index: 0 + type: "int" + returnArg: + index: 0 + type: "int" + selectors: + - matchArgs: + - index: 0 + operator: "Equal" + values: + - "0" + matchActions: + - action: Post + rateLimit: "1m" # Rate limit messages to 1min From 95a44fcb863604a1ca6228e2847a278dc221f230 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Sun, 12 Nov 2023 23:24:49 +0100 Subject: [PATCH 2/3] doc:policylibrary: add setuid system calls to root Signed-off-by: Djalal Harouni --- .../policy-library/observability/_index.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/content/en/docs/policy-library/observability/_index.md b/docs/content/en/docs/policy-library/observability/_index.md index 12ac928e6c2..152a90315a7 100644 --- a/docs/content/en/docs/policy-library/observability/_index.md +++ b/docs/content/en/docs/policy-library/observability/_index.md @@ -19,6 +19,7 @@ description: > - [Binary Execution in /tmp]({{< ref "#tmp-execs" >}}) - [sudo Monitoring]({{< ref "#sudo" >}}) +- [Setuid system calls]({{< ref "#setuid" >}}) ### Networking @@ -160,6 +161,39 @@ jq 'select(.process_exec != null) | select(.process_exec.process.binary | contai "2023-10-31T19:03:35.273111185Z null /usr/bin/sudo -i" ``` +## Setuid System Calls {#setuid} + +### Description + +Monitor execution of the [setuid()](https://www.man7.org/linux/man-pages/man2/setuid.2.html) system calls family. + +### Use Case + +The [setuid()](https://www.man7.org/linux/man-pages/man2/setuid.2.html) and [setgid()](https://www.man7.org/linux/man-pages/man2/setgid.2.html) +system calls family allow to change the effective user ID and group ID of the calling process. + +Detecting [setuid()](https://www.man7.org/linux/man-pages/man2/setuid.2.html) and [setgid()](https://www.man7.org/linux/man-pages/man2/setgid.2.html) calls that set the user ID or group ID to root is a common +best-practice to identify when privileges are raised. + +### Policy + +The [privileges-setuid-root.yaml](https://raw.githubusercontent.com/cilium/tetragon/main/examples/policylibrary/privileges/privileges-setuid-root.yaml) is a catch all to the various interfaces of `setuid()` and `setgid()` to root. + +### Example jq Filter + +```shell-session +jq 'select(.process_kprobe != null) | select(.process_kprobe.policy_name | test("privileges-setuid-root")) | "\(.time) \(.process_kprobe.process.pod.namespace) \(.process_kprobe.process.pod.name) \(.process_kprobe.process.binary) \(.process_kprobe.process.arguments) \(.process_kprobe.function_name) \(.process_kprobe.args)"' +``` + +### Example Output + +```shell-session +"2023-11-12T22:17:40.754680857Z null null /usr/bin/sudo id __sys_setresgid [{\"int_arg\":-1},{\"int_arg\":0},{\"int_arg\":-1}]" +"2023-11-12T22:17:40.754730285Z null null /usr/bin/sudo id __sys_setresuid [{\"int_arg\":-1},{\"int_arg\":0},{\"int_arg\":-1}]" +"2023-11-12T22:17:40.758125709Z null null /usr/bin/sudo id __sys_setgid [{\"int_arg\":0}]" +"2023-11-12T22:17:40.758747395Z null null /usr/bin/sudo id __sys_setresuid [{\"int_arg\":0},{\"int_arg\":0},{\"int_arg\":0}]" +``` + ## SSHd connection monitoring {#ssh-network} ### Description From 10b9707724e488924fcc56b502ed05833699612e Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Mon, 13 Nov 2023 09:25:17 +0100 Subject: [PATCH 3/3] doc:policylibrary: suid binary execution Signed-off-by: Djalal Harouni --- .../policy-library/observability/_index.md | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/docs/content/en/docs/policy-library/observability/_index.md b/docs/content/en/docs/policy-library/observability/_index.md index 152a90315a7..66342f84898 100644 --- a/docs/content/en/docs/policy-library/observability/_index.md +++ b/docs/content/en/docs/policy-library/observability/_index.md @@ -19,6 +19,7 @@ description: > - [Binary Execution in /tmp]({{< ref "#tmp-execs" >}}) - [sudo Monitoring]({{< ref "#sudo" >}}) +- [SUID Binary Execution]({{< ref "#suid" >}}) - [Setuid system calls]({{< ref "#setuid" >}}) ### Networking @@ -161,6 +162,69 @@ jq 'select(.process_exec != null) | select(.process_exec.process.binary | contai "2023-10-31T19:03:35.273111185Z null /usr/bin/sudo -i" ``` +## SUID Binary Execution {#suid} + +### Description + +Monitor execution of SUID "Set User ID" binaries. + +### Use Case + +The "Set User Identity" and "Set Group Identity" are permission flags. When set on a binary file, the binary will execute with the permissions +of the owner or group associated with the executable file, rather than the user executing it. Usually it is used to run programs with elevated privileges to perform specific tasks. + +Detecting the execution of `setuid` and `setgid` binaries is a common +best-practice as attackers may abuse such binaries, or even create them +during an exploit for subsequent execution. + +### Requirement + +Run Tetragon with `enable-process-creds` setting set to enable visibility +into [process_credentials]({{< ref "/docs/reference/grpc-api#processcredentials" >}}) and [binary_properties]({{< ref "/docs/reference/grpc-api#binaryproperties" >}}). + +{{< tabpane lang=shell-session >}} + +{{< tab Kubernetes >}} +kubectl edit cm -n kube-system tetragon-config +# Change "enable-process-cred" from "false" to "true", then save and exit +# Restart Tetragon daemonset +kubectl rollout restart -n kube-system ds/tetragon +{{< /tab >}} +{{< tab docker >}} +docker run --name tetragon --rm -d \ + --pid=host --cgroupns=host --privileged \ + -v /sys/kernel:/sys/kernel \ + -v /var/log/tetragon:/var/log/tetragon \ + quay.io/cilium/tetragon:{{< latest-version >}} \ + /usr/bin/tetragon --enable-process-cred \ + --export-filename /var/log/tetragon/tetragon.log +{{< /tab >}} +{{< tab systemd >}} +# Write to the drop-in file /etc/tetragon/tetragon.conf.d/enable-process-cred true +# Run the following as a privileged user then restart tetragon service +echo "true" > /etc/tetragon/tetragon.conf.d/enable-process-cred +systemctl restart tetragon +{{< /tab >}} +{{< /tabpane >}} + +### Policy + +No policy needs to be loaded, standard process execution observability is sufficient. + +### Example jq Filter + +```shell-session +jq 'select(.process_exec != null) | select(.process_exec.process.binary_properties != null) | select(.process_exec.process.binary_properties.setuid != null or .process_exec.process.binary_properties.setgid != null) | "\(.time) \(.process_exec.process.pod.namespace) \(.process_exec.process.pod.name) \(.process_exec.process.binary) \(.process_exec.process.arguments) uid=\(.process_exec.process.process_credentials.uid) euid=\(.process_exec.process.process_credentials.euid) gid=\(.process_exec.process.process_credentials.gid) egid=\(.process_exec.process.process_credentials.egid)"' +``` + +### Example Output + +```shell-session +"2023-11-13T08:20:43.615672640Z null null /usr/bin/sudo id uid=1000 euid=0 gid=1000 egid=1000" +"2023-11-13T08:20:45.591560940Z null null /usr/bin/wall hello uid=1000 euid=1000 gid=1000 egid=5" +"2023-11-13T08:20:47.036760043Z null null /usr/bin/su - uid=1000 euid=0 gid=1000 egid=1000" +``` + ## Setuid System Calls {#setuid} ### Description