Code Monkey home page Code Monkey logo

demo-cloud-native-ebpf-day's Introduction

LSM BPF Changes Everything

This repository contains the code I used for the demo during my talk @ Cloud Native eBPF Day NA 2021.

Here you'll find the following eBPF programs:

restrict_connect
BPF LSM program (on socket_connect hook) that prevents any connection towards 1.1.1.1 to happen
audit_connect
program that shows BPF LSM for auditing (on socket_connect hook)
kprobe_connect
program that instruments a kprobe on the Kernel function (security_socket_connect) installing the socket_connect hook
trace_net
eBPF program for the net/net_dev_queue tracepoint
trace_connect
eBPF program tracing the entering of the connect syscall

Usage

First thing you'd need to clone this repository, isn't it?

git clone --recurse-submodules -j8 https://github.com/leodido/demo-cloud-native-ebpf-day.git

I guess you wanna now build this machinery. Cool!

Prerequisites

Wait a sec, here are some preconditions to get all of this demo working...

You need a BTF capable Kernel (Linux Kernel 4.18+).

To check whether you have a BTF enabled kernel run:

$ zcat /proc/config.gz | grep CONFIG_DEBUG_INFO_BTF=

Otherwise, you need to recompile you kernel with CONFIG_DEBUG_INFO_BTF=y: it's size will increase of ~1.5MB, not a big deal.

You need to install bpftool and clang.

On ArchLinux this is as easy as running:

$ sudo pacman -S bpf clang

If you also wanna try the BPF LSM programs, you need a Linux Kernel 5.7+ with BPF LSM on.

To check whether you have it enabled or not:

$ zcat /proc/config.gz | grep CONFIG_LSM=

Check if BPF hooks are enabled for LSM by looking at the output to contain them:

CONFIG_LSM="...,bpf"

Remember that BPF hooks for LSM can also be enabled via the lsm Kernel boot parameters, so take a look there too.

Also check your Kernel supports BPF LSM instrumentation with:

$ zcat /proc/config.gz | grep CONFIG_BPF_LSM=

Building

Ok, now you can move to the src directory. Here you'll find a nice Makefile to build all the things at once:

$ make

Or, one by one. For example:

$ make trace_net
$ make V=1 restrict_connect # in case you like to be verbose

Running

Now it's time to run ๐Ÿƒ

Wanna try to restrict connections towards 1.1.1.1? Try this:

$ sudo ./restrict_connect

Then, in another terminal:

$ curl https://1.1.1.1
$ ping 1.1.1.1

And observe the output!

Notice that all the other eBPF programs in this repo (so, except restrict_connect at the moment) work only against connections coming from executables which name is attack_connect.

This means they'll ignore connections generating from curl, etc.

Evaluation

One of the reasons because this repository (and its talk) exist was because I wanted to test an attack (CVE-2021-33505) that in some circumstances (ie., userfaultfd syscall enabled) is able to bypass security auditing tools based on tracepoints (that were not exactly made to accomplish this goal, but still...).

So, I wanted to verify which tracing implementations for the security context are vulnerable to this attack... And here we are. ๐Ÿ™ƒ

Wanna know more about this attack? Watch this DEFCON talk by my friend Xiaofei Rex Guo.

Now, let's say that you wanna try the attack yourself targeting one of the eBPF programs here.

First, you'll need to verify whether you have the `userfaultfd` syscall...

$ zcat /proc/config.gz | grep CONFIG_USERFAULTFD

You'll also need to verify if it is enabled for unprivileged users (surprisingly, it is enabled for unprivileged users in many distro kernels).

$ cat /proc/sys/vm/unprivileged_userfaultfd

If /proc/sys/vm/unprivileged_userfaultfd is set to 0, for the sake of this experimentation set it to 1, like so:

$ sudo sysctl -w vm.unprivileged_userfaultfd=1

Now you should be able to doo you experimentations!

First, start an eBPF program of your choice...

Then, it's attack time:

$ pushd phantom-attack/phantom_v1/
$ make
$ popd
$ ./phantom-attack/phantom_v1/attack_connect

I also wrote a bash script to make these experimentations more straightforward.

Maybe, one day, I'll publish the results of such experimentations among different kernel releases, eBPF programs, etc.

Anyways, you can find it at experiment.sh in this repo and you can execute it by providing the number of times you want the attack to run (let's say 10?) and the eBPF program to target (let's say trace_connect?).

$ ./experiment.sh -i 100 -p trace_connect

Have fun!

~ Leo


Analytics

demo-cloud-native-ebpf-day's People

Contributors

leodido avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

demo-cloud-native-ebpf-day's Issues

restrict_connect doesn't have any effect

hi, i use your restrict_connect, but it doesn't have a effect,
i use ubuntu kernel version 6.2.0-39-generic

libbpf: loading object 'restrict_connect_bpf' from buffer
libbpf: elf: section(3) lsm/socket_connect, size 440, link 0, flags 6, type=1
libbpf: sec 'lsm/socket_connect': found program 'restrict_connect' at insn offset 0 (0 bytes), code size 55 insns (440 bytes)
libbpf: elf: section(4) .rellsm/socket_connect, size 96, link 28, flags 40, type=9
libbpf: elf: section(5) license, size 4, link 0, flags 3, type=1
libbpf: license of restrict_connect_bpf is GPL
libbpf: elf: section(6) .rodata, size 4, link 0, flags 2, type=1
libbpf: elf: section(7) .data, size 38, link 0, flags 3, type=1
libbpf: elf: section(18) .BTF, size 1698, link 0, flags 0, type=1
libbpf: elf: section(20) .BTF.ext, size 476, link 0, flags 0, type=1
libbpf: elf: section(28) .symtab, size 576, link 1, flags 0, type=2
libbpf: looking for externs among 24 symbols...
libbpf: collected 0 externs total
libbpf: map 'restrict.data' (global data): at sec_idx 7, offset 0, flags 400.
libbpf: map 0 is "restrict.data"
libbpf: map 'restrict.rodata' (global data): at sec_idx 6, offset 0, flags 480.
libbpf: map 1 is "restrict.rodata"
libbpf: sec '.rellsm/socket_connect': collecting relocation for section(3) 'lsm/socket_connect'
libbpf: sec '.rellsm/socket_connect': relo #0: insn #22 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 22
libbpf: sec '.rellsm/socket_connect': relo #1: insn #29 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 29
libbpf: sec '.rellsm/socket_connect': relo #2: insn #33 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 33
libbpf: sec '.rellsm/socket_connect': relo #3: insn #39 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 39
libbpf: sec '.rellsm/socket_connect': relo #4: insn #43 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 43
libbpf: sec '.rellsm/socket_connect': relo #5: insn #47 against '.data'
libbpf: prog 'restrict_connect': found data map 0 (restrict.data, sec 7, off 0) for insn 47
libbpf: loading kernel BTF '/sys/kernel/btf/vmlinux': 0
libbpf: map 'restrict.data': created successfully, fd=4
libbpf: map 'restrict.rodata': created successfully, fd=5
libbpf: sec 'lsm/socket_connect': found 4 CO-RE relocations
libbpf: prog 'restrict_connect': relo #0: kind <byte_off> (0), spec is [6] struct sockaddr.sa_family (0:0 @ offset 0)
libbpf: CO-RE relocating [0] struct sockaddr: found target candidate [2804] struct sockaddr in [vmlinux]
libbpf: prog 'restrict_connect': relo #0: matching candidate #0 [2804] struct sockaddr.sa_family (0:0 @ offset 0)
libbpf: prog 'restrict_connect': relo #0: patched insn #7 (LDX/ST/STX) off 0 -> 0
libbpf: prog 'restrict_connect': relo #1: kind <byte_off> (0), spec is [17] struct sockaddr_in.sin_addr.s_addr (0:2:0 @ offset 4)
libbpf: CO-RE relocating [0] struct sockaddr_in: found target candidate [21675] struct sockaddr_in in [vmlinux]
libbpf: prog 'restrict_connect': relo #1: matching candidate #0 [21675] struct sockaddr_in.sin_addr.s_addr (0:2:0 @ offset 4)
libbpf: prog 'restrict_connect': relo #1: patched insn #10 (LDX/ST/STX) off 4 -> 4
libbpf: prog 'restrict_connect': relo #2: kind <type_exists> (8), spec is [26] struct trace_event_raw_bpf_trace_printk___x
libbpf: CO-RE relocating [0] struct trace_event_raw_bpf_trace_printk___x: found target candidate [106230] struct trace_event_raw_bpf_trace_printk in [vmlinux]
libbpf: prog 'restrict_connect': relo #2: matching candidate #0 [106230] struct trace_event_raw_bpf_trace_printk
libbpf: prog 'restrict_connect': relo #2: patched insn #13 (ALU/ALU64) imm 1 -> 1
libbpf: prog 'restrict_connect': relo #3: kind <enumval_exists> (10), spec is [27] enum bpf_func_id___x::BPF_FUNC_snprintf___x = 42
libbpf: CO-RE relocating [0] enum bpf_func_id___x: found target candidate [11292] enum bpf_func_id in [vmlinux]
libbpf: prog 'restrict_connect': relo #3: matching candidate #0 [11292] enum bpf_func_id::BPF_FUNC_snprintf = 165
libbpf: prog 'restrict_connect': relo #3: patched insn #14 (LDIMM64) imm64 1 -> 1
BPF skeleton ok

and when i run ping 1.1.1.1, it also can ping it
i don't know how to resolve it ,can you help me? thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.