Code Monkey home page Code Monkey logo

kunai's Introduction

CI Downloads Discord

GitHub release (with filter) Documentation

Leitmotiv

The goal behind this project is to bring relevant events to achieve various monitoring tasks ranging from security monitoring to Threat Hunting on Linux based systems. If you are familiar with Sysmon on Windows, you can think of Kunai as being a Sysmon equivalent for Linux.

What makes Kunai special ?

  • events arrive sorted in chronological order
  • benefits from on-host correlation and events enrichment
  • works well with Linux namespaces and container technologies (you can trace all the activity happening inside your containers)

How it works

All the kernel components of this project are running as eBPF programs (also called probes). Kunai embeds numbers of probes to monitor relevant information for security monitoring. When the job is done on eBPF side, information is passed on to a userland program which is responsible for various things, such as re-ordering, enriching and correlating events.

On the implementation side, Kunai is written for its majority in Rust, leveraging the awesome Aya library so everything you'll need to run is a standalone binary embedding both all the eBPF probes and the userland program.

FAQ

  • Is it compatible with my OS/Kernel ? : Check out the compatibility page
  • What kind of events can I get ? : Please take a read to events documentation
  • Which version should I use ?: If it is just to test the tool, use the latest build as it is always the best in terms of features and bug fix. However keep in mind that events in non stable releases are subject to change.

How to build the project ?

Before going further, I have to remind you that there is a distribution agnostic (built with musl) pre-compiled version of kunai available in release page. So if you just want to give a try to kunai, you probably don't need to build the project yourself.

Requirements

Before being able to build everything, you need to install a couple of tools.

  • to build many Rust projects (this one included), you need rustup
  • to build kunai you need: clang, libbpf-dev and bpf-linker

Example of commands to install requirements on Ubuntu/Debian:

sudo apt update
sudo apt install -y clang libbpf-dev

# assuming you have rustup and cargo installed
cargo install bpf-linker

Building Kunai

Once you have the requirements installed, you are good to go. You can now build the project with xtask, a cargo command (specific to this project) to make your life easier.

Building debug version

cargo xtask build
# find your executable in: ./target/x86_64-unknown-linux-musl/debug/kunai

Building release version (harder, better, faster, stronger)

cargo xtask build --release
# find your executable in: ./target/x86_64-unknown-linux-musl/release/kunai

Cross-compiling

Let's say you want to cross-compile Kunai for aarch64 using MUSL, so that you have a single static binary at the end.

  1. Install the proper target using rustup rustup install target aarch64-unknown-linux-musl
  2. You need to install an appropriate toolchain to cross-compile to your target on your distribution. When building to a MUSL target, it may work using lld as linker and it works for aarch64-unknown-linux-musl target.
  3. Specify the target you want to build for in the command line and specify the linker to use.
    cargo xtask build --release --target aarch64-unknown-linux-musl --linker /usr/bin/lld
    
    If using lld does not work, you need to find the appropriate linker to use when cross-compiling to the wanted target. Please dig a bit on the internet for that as I don't know them all, and it also depends on your distribution.
  4. You should find your cross-compiled binary at ./target/aarch64-unknown-linux-musl/release/kunai

NB: specifying --linker option is just a shortcut for setting appropriate RUSTFLAGS env variable when building userland application.

Related Work

Sysmon For Linux: https://github.com/Sysinternals/SysmonForLinux

Acknowledgements

  • Thanks to all the people behind Aya, this stuff is just awesome
  • Special thanks to @alessandrod and @vadorovsky
  • Thanks to all the usual guys always supporting my crazy ideas

Funding

The NGSOTI project is dedicated to training the next generation of Security Operation Center (SOC) operators, focusing on the human aspect of cybersecurity. It underscores the significance of providing SOC operators with the necessary skills and open-source tools to address challenges such as detection engineering, incident response, and threat intelligence analysis. Involving key partners such as CIRCL, Restena, Tenzir, and the University of Luxembourg, the project aims to establish a real operational infrastructure for practical training. This initiative integrates academic curricula with industry insights, offering hands-on experience in cyber ranges.

NGSOTI is co-funded under Digital Europe Programme (DEP) via the ECCC (European cybersecurity competence network and competence centre).

kunai's People

Contributors

dependabot[bot] avatar qjerome 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kunai's Issues

IoC scanning

Allow scanning of IoC inside events.

  • IoC configuration file (not to depend of any IoC provider)

remove mount event

Mount event stopped working on 6.6 and needs to be done from scratch to track fsmount syscall.
Initially mount event was introduced, because implementation was already made, so it was zero cost.
The benefit of this event is very limited, as I don't see what real value it brings in terms of security/threat monitoring.
On the other hand it seems this event would need several probes and maybe events to handle all the possible cases and being cross-kernel compatible.
Making the cost/benefit ratio of keeping supporting this event (in a cross-kernel fashion) seems pretty high, so it has been decided to remove it completely from next release (i.e. v0.2.0)

bpf_prog_load event "failed to retrieve bpf_prog instructions" error

Hello,

While building a docker container I get the following errors:

[2023-12-06T12:59:30Z ERROR kunai] failed to retrieve bpf_prog instructions: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })
[2023-12-06T12:59:30Z ERROR kunai] failed to retrieve bpf_prog instructions: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })
[2023-12-06T12:59:46Z ERROR kunai] failed to retrieve bpf_prog instructions: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })
[2023-12-06T12:59:46Z ERROR kunai] failed to retrieve bpf_prog instructions: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })

Using the latest binary (v0.1.0).

What might be the reason?

BufferError in ubuntu 20.04

uname: 5.4.0-170-generic #188-Ubuntu SMP Wed Jan 10 09:51:01 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

probes::send_data line=19 tgid=659 comm=snapd BufferError: unimplemented iter

aarch64 compability

Some features aren't working on aarch64

Linux version
Linux debian 6.1.0-22-arm64 #1 SMP Debian 6.1.94-1 (2024-06-21) aarch64 GNU/Linux

Some stats on the error log file (running for a few hours)
cat error.log | cut -d " " -f 4 | sort | uniq -c

    280 probes::clone
    159 probes::connect
    192 probes::execve
16407863 probes::fs
   3613 probes::send_data
... [other errors]

Schedule probe "failed to read argv" error

Hello,

Getting the following errors:

[2023-12-05T19:36:26Z ERROR kunai_ebpf::probes::schedule] failed to read argv
[2023-12-05T19:36:26Z ERROR kunai_ebpf::probes::schedule] failed to read argv
[2023-12-05T19:36:26Z ERROR kunai_ebpf::probes::schedule] failed to read argv

Using the latest binary (v0.1.0).

What might be the reason?

Update to latest Aya

Lots of changes happened in Aya and kunai need to be updated accordingly:

  • fix for bpf_probe_read_user_str_bytes helper of empty strings
  • fix to be compatible with rust nightly

An upgrade attempt has been made but an issue was encountered: aya-rs/aya#808

Machine Id

In .info.host section, put a machine UUID in case the hostname changes.

  • use a derive of /etc/machine-id
  • make it configurable in config file

Error message not explicit enough

The following happens because the file executed got deleted before the userland program could retrieve its hash.
Currently an error message is reported. Either make the error message more explicit or generate an event when such a case happens.

Example:

  "data": {
    "ancestors": "/usr/lib/systemd/systemd|/usr/sbin/sshd|/usr/sbin/sshd|/usr/sbin/sshd|/usr/bin/bash|/usr/bin/sudo|/usr/bin/su|/usr/bin/bash|/tmp/bpfdoor.mwr|/usr/bin/dash",
    "parent_exe": "/usr/bin/dash",
    "command_line": "/dev/shm/kdmtmpflush --init",
    "exe": {
      "file": "/dev/shm/kdmtmpflush",
      "md5": "",
      "sha1": "",
      "sha256": "",
      "sha512": "",
      "size": 0,
      "error": "hash not found"
    },
    "interpreter": {
      "file": "/dev/shm/kdmtmpflush",
      "md5": "",
      "sha1": "",
      "sha256": "",
      "sha512": "",
      "size": 0,
      "error": "hash not found"
    }
  }

Info when parent is kernel

When parent_exe is the kernel, the field value is currently ?, this must be changed to another value.
One can identify whether parent task is KTHREAD

{
  "data": {
    "ancestors": "?|?|?",
    "parent_exe": "?",
    "command_line": "/sbin/modprobe -q -- net-pf-10",
    "exe": {
      "file": "/usr/bin/kmod",
      "md5": "b14b91a0bb23dc63c89adb1e0da886b4",
      "sha1": "3482856787ce9b659039092bdfb06fa65775e8a6",
      "sha256": "4c756856466594ba8be8af34ad827e546a966e9392404be89e11ad5efa525afe",
      "sha512": "01bfc892c6f863523385f9edd10aac2de59bd918d0c9cefdc364052b57dcc8f40018172a18ea4ff0614fc3aab378f750bd090d46f4c2efbd2a37c9405050f8af",
      "size": 166008
    }
  },
  "info": {
    "host": {
      "hostname": "whiterose",
      "container": null
    },
    "event": {
      "source": "kunai",
      "id": 1,
      "name": "execve",
      "uuid": "6b19e669-ecc2-4aab-fba4-b57d73a82ec9",
      "batch": 14
    },
    "task": {
      "name": "modprobe",
      "pid": 72088,
      "tgid": 72088,
      "guuid": "6de76f27-4312-0000-0d52-d89898190100",
      "uid": 0,
      "gid": 0,
      "namespaces": {
        "mnt": 4026531841
      },
      "flags": "0x400000"
    },
    "parent_task": {
      "name": "kworker/u16:1",
      "pid": 55275,
      "tgid": 55275,
      "guuid": "0606a127-630e-0000-0d52-d898ebd70000",
      "uid": 0,
      "gid": 0,
      "namespaces": {
        "mnt": 4026531841
      },
      "flags": "0x4208060"
    },
    "utc_time": "2024-01-03T15:24:24.250472947Z"
  }
}

Fix path in latest LTS

In latest LTS a bug shown up and raised the following error: failed to resolve exe: failed to read dentry ctime

Root cause: between kernel 6.5 and 6.6 struct inode changed. More specifically, the ctime field got renamed to __ctime which brakes the shim currently in place. This needs to be fixed at shim level.

ancestor field on all events

Ancestors is a way to bring context to every event, as it allows to track where the event comes from. It is sometimes the only way to identify whether a specific event is suspicious or not.
So it would be really nice to have this field in every event.

Data model harmonization.

Hello,

For execve events, the data.exe field is an object. For events like read_config and file_unlink, the data.exe field is a string.

To ease data ingestion it could make sense to use the same data type for a specific field name.

improve hostname correlation

So far hostname correlation works only a per process basis.
That means that if process A resolves test.com only IPs matching this hostname in this process will be correlated back.
We could extend the resolution table to also work on a system basis, while keeping the per process resolution table.
The system resolution table would be used only as a fallback.

Cgroup parsing errors

When using kunai to monitor Kubernetes containers @blightzero reported that lots of error messages regarding cgroups gets generated.
This is very likely a bug !

ERROR kunai_ebpf::probes::clone] failed to resolve cgroup: failed appending to path
ERROR kunai_ebpf::probes::execve] failed to resolve cgroup: failed appending to path
ERROR kunai_ebpf::probes::schedule] CgroupError

Setup: Kernel 6.1.0 from Debian backports

send_data issue on debian 12

send_data probe seems not to work on debian 12 (bookworm)

Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm

Kernel: 6.1.0-21-amd64

handle bpf socket attach

Socket filter attached has been addressed in #3, however there are other ways to attach BPFs program to socket.

Both the API use the already hooked functions __sk_attach_prog and reusedport_attach_prog so it should be a special case to handle in handle_socket_attach_prog function.

For the moment a warning is displayed when a BPF program gets attached to a socket !

NB: as I understand the kernel code, the BPF program first needs to be loaded before being attached. So it is likely we would see a bpf_prog_load event prior to attach event.

Issue with kretprobes not surviving to suspend/resume cycle

Kunai suffers from an issue with kretprobes not working after a cycle of suspend/resume.
After investigation, this bug is not related to Kunai itself nor Aya. After some discussion with Aya folks we concluded that it is very likely a Linux kernel bug. A issue has been created to track down this bug: https://bugzilla.kernel.org/show_bug.cgi?id=218775
Even though the bug, very likely happen in the kernel, we can find a way to fix it in Kunai by reloading programs when system resumes.
This can be achieved by attaching a kprobe to syscore_resume function.

Error in prctl probe

Rarely an error appears in prctl probe, mostly when spinning a new docker container.

2024-01-29T15:06:55Z ERROR kunai_ebpf::probes::prctl] line:44 BpfMapError

Guessed root cause: the LruHashmap was not explicitely cleaned up and I think this may be an issue when entries arrive too quickly (i.e. some relevant entries are overwritten because the LruHashmap cannot know which one to remove better than us). After testing with explicit map cleanup, the error does not show up anymore.

Error in clone probe

Sometimes when docker containers get started this error pops up

[2024-01-29T11:10:26Z ERROR kunai_ebpf::probes::clone] line:11 EventError

can't find executable

after a successful build, I can't find the executable

root@deb12:/kunai# pwd
/root/kunai
root@deb12:
/kunai# find . -iname "kunai*" -type f
root@deb12:~/kunai#

BufferError in latest Linux LTS

send_data probe returns ERROR kunai_ebpf::probes::send_data] BufferError

This is caused because iov member of struct iov_iter got renamed to __iov.
Shim needs to be fixed accordingly

Rework errors in BPF

  • switch the display of some errors to warnings
  • define own way to transmit errors to userland (do not rely on aya log anymore)

DNS probe KProbeCtxRestoreFailure

Hello,

Getting the following errors:

[2023-12-05T18:49:47Z ERROR kunai_ebpf::probes::dns] KProbeCtxRestoreFailure
[2023-12-05T19:01:47Z ERROR kunai_ebpf::probes::dns] KProbeCtxRestoreFailure
[2023-12-05T19:13:47Z ERROR kunai_ebpf::probes::dns] KProbeCtxRestoreFailure

Using the latest binary (v0.1.0).

What might be the reason?

Overwrite Event

It is currently possible to monitor Write events, however such events may be too many for some systems (servers for instance).
In order to reduce the amount of Write events, one idea would be to catch only writes at a given position (within 1024 first bytes for instance).

  1. try to find if it is really making sense ?
  2. if it can be implement in Write events or if it needs a new event being created ?

Improve container information in events

So far it is not very clear when an event comes from a container or not.
As the notion of container is a completely abstract notion built around Linux namespaces, we could consider (in kunai) a container is a process having a different mount namespace from the kunai process.

Clone event has wrong information

Following fix #38 clone event present wrong data in .info.task, it presents information about the thread before being completely forked/cloned. As a result, we lose information some information about new threads.

Bug when trying to match container in rules

Such a rule generates errors when trying to match

name: docker
params:
    filter: true
match-on:
    events:
        # match any event
        kunai: []
matches:
    $docker: .info.host.container.type == 'docker'
condition: $docker

Issue: .info.host.container may be null and the event matching engine consider it as an error as it cannot find the field type within container object. This is a wanted behavior to show people when they do mistake in their rules.

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.