Git Product home page Git Product logo

bad-bpf's Introduction

Bad BPF

A collection of malicious eBPF programs that make use of eBPF's ability to read and write user data in between the usermode program and the kernel.

Overview

See my blog and my DEF CON talk for an overview on how thee programs work and why this is interesting.

Examples have been tested on:

  • Ubuntu 22.04

Build

To use pre-build binaries, grab them from the Releases page.

To build from source, do the following:

Dependecies

To build and run all the examples, you will need a Linux kernel version of at least 4.7.

As this code makes use of CO-RE, it requires a recent version of Linux that has BTF Type information. See these notes in the libbpf README for more information. For example Ubuntu requries Ubuntu 20.10+.

To build it requires these dependecies:

  • zlib
  • libelf
  • libbfd
  • clang and llvm 14
  • make

On Ubuntu these can be installed by

sudo apt install build-essential clang-14 llvm-14 libelf1 libelf-dev zlib1g-dev libbfd-dev libcap-dev linux-tools-common linux-tools-generic

Build

To Build from source, recusivly clone the respository the run make in the src directory to build:

# --recursive is needed to also get the libbpf source
git clone --recursive https://github.com/pathtofile/bad-bpf.git
cd bad-bpf/src
make

The binaries will built into bad-bpf/src/. If you encounter issues with related to vmlinux.h, try remaking the file for your specific kernel and distribution:

cd bad-bpf/tools
./bpftool btf dump file /sys/kernel/btf/vmlinux format c > ../vmlinux/<arch>/vmlinux.h

Run

To run, launch each program as root. Every program has a --help option that has required arguemnts and examples.

Programs

Common Arguments

As well as --help, every program also has a --target-ppid/-t. This option restricts the programs' operation to only programs that are children of the process matching this PID. This demonstrates to how affect some programs, but not others.

BPF-Dos

sudo ./bpfdos

This program raises a SIG_KILL signal to any program attempting to use the ptrace syscall, e.g. strace. Once bpf-dos starts you can test it by running:

strace /bin/whoami

Exec-Hijack

sudo ./exechijack

This program intercepts all execve calls (used to create new processes) and instead makes then call /a. To run, first ensure there is a program in the root dir /a (probably best to make is executable by all). bad-bpf builds a simple program hijackee that simply prints out the uid and argv[0], so you can use that:

make
sudo cp ./hijackee /a
sudo chmod ugo+rx /a

Then just run sudo ./exechijack.

Pid-Hide

sudo ./pidhide --pid-to-hide 2222

This program hides the process matching this pid from tools such as ps.

It works by hooking the getdents64 syscall, as ps works by looking for every sub-folder of /proc/. PidHide unlinks the folder matching the PID, so ps only sees the folders before and after it.

Sudo-Add

sudo ./sudoadd --username lowpriv-user

This program allows a normally low-privledged user to use sudo to become root.

It works by intercepting sudo's reading of the /etc/sudoers file, and overwriting the first line with <username> ALL=(ALL:ALL) NOPASSWD:ALL #. This tricks sudo into thinking the user is allowed to become root. Other programs such as cat or sudoedit are unnafected, so to those programs the file is unchanged and the user does not have those privliges. The # at the end of the line ensures the rest of the line is trated as a comment, so it doesn't currup the file's logic.

Write-Blocker

sudo ./writeblocker --pid 508

This program intercepts all write syscall for a given process PID. Instead of passing the data to the actual write syscall, writeblocker will instead fake the call, returning the same number of bytes that the userspaceprogram expects to be written.

Only File Descriptors > 2 will be blocked, so stdin, stdout, and stderror still work.

For example, if you block the writes for the rsyslogd process, ssh logins will not be written to /var/log/auth.log.

Text-Replace

sudo ./textreplace --filename /path/to/file --input foo --replace bar

This program replaces all text matching input in the file with the replace text. This has a number of uses, for example:

To hide kernel module joydev from tools such as lsmod:

./textreplace -f /proc/modules -i 'joydev' -r 'cryptd'

Spoof the MAC address of the eth0 interface:

/textreplace -f /sys/class/net/eth0/address -i '00:15:5d:01:ca:05' -r '00:00:00:00:00:00'

Malware conducting anti-sandbox checks might check the MAC address to look for signs it is running inside a Virtual Machine or Sandbox, and not on a 'real' machine.

NOTE: Both input and replace must be the same length, to avoid adding NULL characters to the middle of a block of text. To enter a newline from a bash prompt, use $'\n', e.g. --replace $'text\n'.

Text-Replace2

This program works the same as Text-Replace, however it has two extra features:

  • The program's configuration is alterable at runtime using eBPF Maps.
  • The userspace loader can detach and exit

Altering Configuration

The filename is stored in the eBPF Map map_filename. The Key is always 0, and the value matches this struct:

struct tr_file {
    char filename[50];
    unsigned int filename_len;
};

That is, 50 ascii characters, then an unsigned int mathcing the length of the actual filename string.

The easiest way to view and alter eBPF maps is using bpftool:

# List current config
$> bpftool map dump name map_filename
[{
        "key": 0,
        "value": {
            "filename": "/proc/modules",
            "filename_len": 13
        }
    }
]

# Alter filename to be 'AAAA'
$> bpftool map update name map_filename \
    key hex 00 00 00 00 \
    value hex 61 61 61 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00

# Confirm change config
$> bpftool map dump name map_filename
[{
        "key": 0,
        "value": {
            "filename": "aaaa",
            "filename_len": 4
        }
    }
]

To alter the text to find and replace, alter the items in the Map map_text. The text to find is at key 0, and the text to replace is key 1. The values will each match this struct:

struct tr_text {
    char text[20];
    unsigned int text_len;
};

Running Detached

By running the program with --detach, the userspace loader can exit without stopping the eBPF Programs. Before running, first make sure the bpf filesystem is mounted:

sudo mount bpffs -t bpf /sys/fs/bpf

Then you can run text-replace2 detached:

./textreplace2 -f /proc/modules -i 'joydev' -r 'cryptd' --detach

This will create a number of eBPF Link files under /sys/fs/bpf/textreplace. Once loader has sucessfully run, you can check the logs by running:

sudo cat /sys/kernel/debug/tracing/trace_pipe
# confirm link files are there
sudo ls -l /sys/fs/bpf/textreplace

Then to stop, simply delete the link files:

sudo rm -r /sys/fs/bpf/textreplace

bad-bpf's People

Contributors

pathtofile 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

bad-bpf's Issues

error in backend: Unsupported dynamic stack allocation

Cloned code cannot dynamically allocate addresses during compilation. What is the reason for this?

pidhide.bpf.c:57:21: warning: variable length array folded to constant array as an extension [-Wgnu-folding-constant]
const volatile char pid_to_hide[max_pid_len];
^
fatal error: error in backend: Unsupported dynamic stack allocation
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: clang -g -O2 -target bpf -D__TARGET_ARCH_x86 -I.output -idirafter /usr/local/include -idirafter /usr/lib/llvm-12/lib/clang/12.0.1/include -idirafter /usr/include/x86_64-linux-gnu -idirafter /usr/include -c pidhide.bpf.c -o .output/pidhide.bpf.o

  1. parser at end of file
  2. Code generation
  3. Running pass 'Function Pass Manager' on module 'pidhide.bpf.c'.
  4. Running pass 'BPF DAG->DAG Pattern Instruction Selection' on function '@handle_getdents_exit'
    Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var LLVM_SYMBOLIZER_PATH to point to it):
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamEi+0x31)[0x7fa81870d871]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm3sys17RunSignalHandlersEv+0x50)[0x7fa81870b9a0]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm3sys15CleanupOnSignalEm+0x100)[0x7fa81870cf00]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(+0xc746ba)[0x7fa81865b6ba]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(+0xc7465b)[0x7fa81865b65b]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm3sys7Process4ExitEib+0x27)[0x7fa818708047]
    clang[0x412dc0]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm18report_fatal_errorERKNS_5TwineEb+0x122)[0x7fa818667ab2]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(+0xc80986)[0x7fa818667986]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(+0x2a4e68f)[0x7fa81a43568f]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(+0x130679b)[0x7fa818ced79b]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm12SelectionDAG8LegalizeEv+0x1a5)[0x7fa818cecd45]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm16SelectionDAGISel17CodeGenAndEmitDAGEv+0x48d)[0x7fa818e2ce9d]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm16SelectionDAGISel20SelectAllBasicBlocksERKNS_8FunctionE+0x185a)[0x7fa818e2c40a]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm16SelectionDAGISel20runOnMachineFunctionERNS_15MachineFunctionE+0x796)[0x7fa818e29f96]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm19MachineFunctionPass13runOnFunctionERNS_8FunctionE+0xfe)[0x7fa818a2f60e]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm13FPPassManager13runOnFunctionERNS_8FunctionE+0x3a0)[0x7fa8188414f0]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm13FPPassManager11runOnModuleERNS_6ModuleE+0x33)[0x7fa8188470a3]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm6legacy15PassManagerImpl3runERNS_6ModuleE+0x3a8)[0x7fa818841af8]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang17EmitBackendOutputERNS_17DiagnosticsEngineERKNS_19HeaderSearchOptionsERKNS_14CodeGenOptionsERKNS_13TargetOptionsERKNS_11LangOptionsERKN4llvm10DataLayoutEPNSE_6ModuleENS_13BackendActionESt10unique_ptrINSE_17raw_pwrite_streamESt14default_deleteISM_EE+0x2dc6)[0x7fa81eaabac6]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(+0x1856fae)[0x7fa81ed58fae]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang8ParseASTERNS_4SemaEbb+0x254)[0x7fa81de43d34]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang13CodeGenAction13ExecuteActionEv+0x223)[0x7fa81ed55c03]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang14FrontendAction7ExecuteEv+0x56)[0x7fa81f48f456]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x8b1)[0x7fa81f417331]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0x646)[0x7fa81f4f68e6]
    clang(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x9b9)[0x412ab9]
    clang[0x410dbf]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(+0x1c1b942)[0x7fa81f11d942]
    /lib/x86_64-linux-gnu/libLLVM-12.so.1(_ZN4llvm20CrashRecoveryContext9RunSafelyENS_12function_refIFvvEEE+0xdd)[0x7fa81865b63d]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZNK5clang6driver10CC1Command7ExecuteEN4llvm8ArrayRefINS2_8OptionalINS2_9StringRefEEEEEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPb+0x140)[0x7fa81f11d0d0]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(ZNK5clang6driver11Compilation14ExecuteCommandERKNS0_7CommandERPS3+0x190)[0x7fa81f0f0b10]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZNK5clang6driver11Compilation11ExecuteJobsERKNS0_7JobListERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0x8a)[0x7fa81f0f0efa]
    /lib/x86_64-linux-gnu/libclang-cpp.so.12(_ZN5clang6driver6Driver18ExecuteCompilationERNS0_11CompilationERN4llvm15SmallVectorImplISt4pairIiPKNS0_7CommandEEEE+0xdc)[0x7fa81f1065cc]
    clang(main+0x2529)[0x410629]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7fa8174cb083]
    clang(_start+0x2e)[0x40ddce]
    clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
    Ubuntu clang version 12.0.1-++20211029101322+fed41342a82f-1exp120211029221816.4
    Target: bpf
    Thread model: posix
    InstalledDir: /usr/bin
    clang: note: diagnostic msg:

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/pidhide-10b8aa.c
clang: note: diagnostic msg: /tmp/pidhide-10b8aa.sh
clang: note: diagnostic msg:


make: *** [Makefile:62: .output/pidhide.bpf.o] Error 70

Is it possible to use it on CentOS 7.5

Hi, great project! I tried to use it under centos7.5 and it has been compiled successfully.
This is my kernel information: 4.18.0-305.3.1.el8.x86_64 #1 SMP Tue Jun 1 16:14:33 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux.
I try to run a process and hide it:

sleep 1000
sudo ./pidhide -p 29357

Did not succeed (I know it was tested on Ubuntu 20.10 and Fedora 34, but I still want to try it on centos. Is there a way?):

libbpf: loading object 'pidhide_bpf' from buffer
libbpf: elf: section(2) tp/syscalls/sys_enter_getdents64, size 296, link 0, flags 6, type=1
libbpf: sec 'tp/syscalls/sys_enter_getdents64': found program 'handle_getdents_enter' at insn offset 0 (0 bytes), code size 37 insns (296 bytes)
libbpf: elf: section(3) tp/syscalls/sys_exit_getdents64, size 2248, link 0, flags 6, type=1
libbpf: sec 'tp/syscalls/sys_exit_getdents64': found program 'handle_getdents_exit' at insn offset 0 (0 bytes), code size 146 insns (1168 bytes)
libbpf: sec 'tp/syscalls/sys_exit_getdents64': found program 'handle_getdents_patch' at insn offset 146 (1168 bytes), code size 135 insns (1080 bytes)
libbpf: elf: section(4) license, size 13, link 0, flags 3, type=1
libbpf: license of pidhide_bpf is Dual BSD/GPL
libbpf: elf: section(5) .rodata, size 22, link 0, flags 2, type=1
libbpf: elf: section(6) .maps, size 144, link 0, flags 3, type=1
libbpf: elf: section(7) .rodata.str1.1, size 66, link 0, flags 32, type=1
libbpf: elf: skipping unrecognized data section(7) .rodata.str1.1
libbpf: elf: section(8) .BTF, size 27248, link 0, flags 0, type=1
libbpf: elf: section(9) .BTF.ext, size 2388, link 0, flags 0, type=1
libbpf: elf: section(10) .eh_frame, size 112, link 0, flags 2, type=1
libbpf: elf: skipping unrecognized data section(10) .eh_frame
libbpf: elf: section(11) .symtab, size 696, link 18, flags 0, type=2
libbpf: elf: section(12) .reltp/syscalls/sys_enter_getdents64, size 32, link 11, flags 0, type=9
libbpf: elf: section(13) .reltp/syscalls/sys_exit_getdents64, size 288, link 11, flags 0, type=9
libbpf: elf: section(16) .rel.eh_frame, size 48, link 11, flags 0, type=9
libbpf: elf: skipping relo section(16) .rel.eh_frame for section(10) .eh_frame
libbpf: looking for externs among 29 symbols...
libbpf: collected 0 externs total
libbpf: map 'map_buffs': at sec_idx 6, offset 0.
libbpf: map 'map_buffs': found type = 1.
libbpf: map 'map_buffs': found key [8], sz = 8.
libbpf: map 'map_buffs': found value [11], sz = 8.
libbpf: map 'map_buffs': found max_entries = 8192.
libbpf: map 'map_bytes_read': at sec_idx 6, offset 32.
libbpf: map 'map_bytes_read': found type = 1.
libbpf: map 'map_bytes_read': found key [8], sz = 8.
libbpf: map 'map_bytes_read': found value [2], sz = 4.
libbpf: map 'map_bytes_read': found max_entries = 8192.
libbpf: map 'map_prog_array': at sec_idx 6, offset 64.
libbpf: map 'map_prog_array': found type = 3.
libbpf: map 'map_prog_array': found key [23], sz = 4.
libbpf: map 'map_prog_array': found value [23], sz = 4.
libbpf: map 'map_prog_array': found max_entries = 5.
libbpf: map 'map_to_patch': at sec_idx 6, offset 96.
libbpf: map 'map_to_patch': found type = 1.
libbpf: map 'map_to_patch': found key [8], sz = 8.
libbpf: map 'map_to_patch': found value [11], sz = 8.
libbpf: map 'map_to_patch': found max_entries = 8192.
libbpf: map 'rb': at sec_idx 6, offset 128.
libbpf: map 'rb': found type = 27.
libbpf: map 'rb': found max_entries = 262144.
libbpf: map 'pidhide_.rodata' (global data): at sec_idx 5, offset 0, flags 480.
libbpf: map 5 is "pidhide_.rodata"
libbpf: sec '.reltp/syscalls/sys_enter_getdents64': collecting relocation for section(2) 'tp/syscalls/sys_enter_getdents64'
libbpf: sec '.reltp/syscalls/sys_enter_getdents64': relo #0: insn #3 against 'target_ppid'
libbpf: prog 'handle_getdents_enter': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 3
libbpf: sec '.reltp/syscalls/sys_enter_getdents64': relo #1: insn #31 against 'map_buffs'
libbpf: prog 'handle_getdents_enter': found map 0 (map_buffs, sec 6, off 0) for insn #31
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': collecting relocation for section(3) 'tp/syscalls/sys_exit_getdents64'
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #0: insn #12 against 'map_buffs'
libbpf: prog 'handle_getdents_exit': found map 0 (map_buffs, sec 6, off 0) for insn #12
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #1: insn #24 against 'map_bytes_read'
libbpf: prog 'handle_getdents_exit': found map 1 (map_bytes_read, sec 6, off 32) for insn #24
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #2: insn #31 against 'pid_to_hide_len'
libbpf: prog 'handle_getdents_exit': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 31
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #3: insn #39 against 'map_to_patch'
libbpf: prog 'handle_getdents_exit': found map 3 (map_to_patch, sec 6, off 96) for insn #39
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #4: insn #59 against 'map_bytes_read'
libbpf: prog 'handle_getdents_exit': found map 1 (map_bytes_read, sec 6, off 32) for insn #59
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #5: insn #64 against 'map_prog_array'
libbpf: prog 'handle_getdents_exit': found map 2 (map_prog_array, sec 6, off 64) for insn #64
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #6: insn #102 against 'pid_to_hide'
libbpf: prog 'handle_getdents_exit': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 102
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #7: insn #119 against 'map_bytes_read'
libbpf: prog 'handle_getdents_exit': found map 1 (map_bytes_read, sec 6, off 32) for insn #119
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #8: insn #123 against 'map_buffs'
libbpf: prog 'handle_getdents_exit': found map 0 (map_buffs, sec 6, off 0) for insn #123
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #9: insn #129 against 'map_prog_array'
libbpf: prog 'handle_getdents_exit': found map 2 (map_prog_array, sec 6, off 64) for insn #129
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #10: insn #136 against 'map_bytes_read'
libbpf: prog 'handle_getdents_exit': found map 1 (map_bytes_read, sec 6, off 32) for insn #136
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #11: insn #140 against 'map_buffs'
libbpf: prog 'handle_getdents_exit': found map 0 (map_buffs, sec 6, off 0) for insn #140
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #12: insn #150 against 'map_to_patch'
libbpf: prog 'handle_getdents_patch': found map 3 (map_to_patch, sec 6, off 96) for insn #4
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #13: insn #177 against 'pid_to_hide_len'
libbpf: prog 'handle_getdents_patch': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 31
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #14: insn #185 against 'pid_to_hide_len'
libbpf: prog 'handle_getdents_patch': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 39
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #15: insn #214 against 'pid_to_hide_len'
libbpf: prog 'handle_getdents_patch': found data map 5 (pidhide_.rodata, sec 5, off 0) for insn 68
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #16: insn #253 against 'rb'
libbpf: prog 'handle_getdents_patch': found map 4 (rb, sec 6, off 128) for insn #107
libbpf: sec '.reltp/syscalls/sys_exit_getdents64': relo #17: insn #276 against 'map_to_patch'
libbpf: prog 'handle_getdents_patch': found map 3 (map_to_patch, sec 6, off 96) for insn #130
libbpf: loading kernel BTF '/sys/kernel/btf/vmlinux': 0
libbpf: map 'map_buffs': created successfully, fd=4
libbpf: map 'map_bytes_read': created successfully, fd=5
libbpf: map 'map_prog_array': created successfully, fd=6
libbpf: map 'map_to_patch': created successfully, fd=7
libbpf: map 'rb': created successfully, fd=8
libbpf: map 'pidhide_.rodata': created successfully, fd=9
libbpf: sec 'tp/syscalls/sys_enter_getdents64': found 3 CO-RE relocations
libbpf: prog 'handle_getdents_enter': relo #0: kind <byte_off> (0), spec is [46] struct task_struct.real_parent (0:57 @ offset 1184)
libbpf: CO-RE relocating [0] struct task_struct: found target candidate [152] struct task_struct in [vmlinux]
libbpf: prog 'handle_getdents_enter': relo #0: matching candidate #0 [152] struct task_struct.real_parent (0:61 @ offset 2320)
libbpf: prog 'handle_getdents_enter': relo #0: patched insn #8 (ALU/ALU64) imm 1184 -> 2320
libbpf: prog 'handle_getdents_enter': relo #1: kind <byte_off> (0), spec is [46] struct task_struct.tgid (0:55 @ offset 1172)
libbpf: prog 'handle_getdents_enter': relo #1: matching candidate #0 [152] struct task_struct.tgid (0:59 @ offset 2308)
libbpf: prog 'handle_getdents_enter': relo #1: patched insn #15 (ALU/ALU64) imm 1172 -> 2308
libbpf: prog 'handle_getdents_enter': relo #2: kind <byte_off> (0), spec is [36] struct trace_event_raw_sys_enter.args[1] (0:2:1 @ offset 24)
libbpf: CO-RE relocating [0] struct trace_event_raw_sys_enter: found target candidate [5505] struct trace_event_raw_sys_enter in [vmlinux]
libbpf: prog 'handle_getdents_enter': relo #2: matching candidate #0 [5505] struct trace_event_raw_sys_enter.args[1] (0:2:1 @ offset 24)
libbpf: prog 'handle_getdents_enter': relo #2: patched insn #25 (LDX/ST/STX) off 24 -> 24
libbpf: sec 'tp/syscalls/sys_exit_getdents64': found 6 CO-RE relocations
libbpf: prog 'handle_getdents_exit': relo #0: kind <byte_off> (0), spec is [315] struct trace_event_raw_sys_exit.ret (0:2 @ offset 16)
libbpf: CO-RE relocating [0] struct trace_event_raw_sys_exit: found target candidate [5506] struct trace_event_raw_sys_exit in [vmlinux]
libbpf: prog 'handle_getdents_exit': relo #0: matching candidate #0 [5506] struct trace_event_raw_sys_exit.ret (0:2 @ offset 16)
libbpf: prog 'handle_getdents_exit': relo #0: patched insn #4 (LDX/ST/STX) off 16 -> 16
libbpf: prog 'handle_getdents_exit': relo #1: kind <byte_off> (0), spec is [318] struct linux_dirent64.d_reclen (0:2 @ offset 16)
libbpf: CO-RE relocating [0] struct linux_dirent64: found target candidate [31970] struct linux_dirent64 in [vmlinux]
libbpf: prog 'handle_getdents_exit': relo #1: matching candidate #0 [31970] struct linux_dirent64.d_reclen (0:2 @ offset 16)
libbpf: prog 'handle_getdents_exit': relo #1: patched insn #79 (ALU/ALU64) imm 16 -> 16
libbpf: prog 'handle_getdents_exit': relo #2: kind <byte_off> (0), spec is [318] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_exit': relo #2: matching candidate #0 [31970] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_exit': relo #2: patched insn #86 (ALU/ALU64) imm 19 -> 19
libbpf: prog 'handle_getdents_patch': relo #3: kind <byte_off> (0), spec is [318] struct linux_dirent64.d_reclen (0:2 @ offset 16)
libbpf: prog 'handle_getdents_patch': relo #3: matching candidate #0 [31970] struct linux_dirent64.d_reclen (0:2 @ offset 16)
libbpf: prog 'handle_getdents_patch': relo #3: patched insn #11 (ALU/ALU64) imm 16 -> 16
libbpf: prog 'handle_getdents_patch': relo #4: kind <byte_off> (0), spec is [318] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_patch': relo #4: matching candidate #0 [31970] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_patch': relo #4: patched insn #29 (ALU/ALU64) imm 19 -> 19
libbpf: prog 'handle_getdents_patch': relo #5: kind <byte_off> (0), spec is [318] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_patch': relo #5: matching candidate #0 [31970] struct linux_dirent64.d_name (0:4 @ offset 19)
libbpf: prog 'handle_getdents_patch': relo #5: patched insn #65 (ALU/ALU64) imm 19 -> 19
libbpf: load bpf program failed: Permission denied
libbpf: -- BEGIN DUMP LOG ---

There is too much content here, I omitted it

libbpf: -- END LOG --
libbpf: failed to load program 'handle_getdents_exit'
libbpf: failed to load object 'pidhide_bpf'
libbpf: failed to load BPF skeleton 'pidhide_bpf': -4007
Failed to load and verify BPF skeleton

Get it work on Ubuntu20.10 smoothly

Hello, I'm a beginner in eBPF field and after several struggling, I managed to get it work on my Ubuntu 20.10.
So I assume that there is some information needed for beginners like me, and it would be great if some of it can be added to README.md

Clone the project

First of all, to clone the project, the command worked for me is this:

git clone  https://github.com/pathtofile/bad-bpf.git --recusrive

the sequence of "--recursive" actually matters.

Install needed libraries and tools first

Install all these needed stuffs by this command

apt install build-essential clang-11 libelf-dev zlib1g-dev libbfd-dev libcap-dev libbfd-dev  linux-tools-common linux-tools-generic

I didn't find "libfd-dev" provided in README.md, so I guess it is "libbfd-dev"

generate vmlinux.h locally with bpftool

The vmlinux.h provided occurred erros during compiling if you use Ubuntu20.10 like me.
So generating one locally is needed.

cd bad-bpf/src/
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

change clang versions in Makefile

This project work against clang-11, and I didn't find easy to to swtich clang version, so changing contents in Makefile while compiling might be a plausible option

Change contents in Makefile from

CLANG ?= clang
LLVM_STRIP ?= llvm-strip

to

CLANG ?= clang-11
LLVM_STRIP ?= llvm-strip-11

happy compiling

make

libbpf: failed to find BTF for extern 'PT_REGS_PARM1': -2

env:Android 13,Debian 11.7。
kernel:5.10.149.
Replaced bpftool in tools with ARM64

root@localhost:/home/bad-bpf/src# zcat /proc/config.gz | grep BTF
# CONFIG_VIDEO_SONY_BTF_MPX is not set
CONFIG_DEBUG_INFO_BTF=y

root@localhost:/home/bad-bpf/src# make
  BINARY   exechijack
writeblocker.bpf.c:29:14: warning: implicit declaration of function 'PT_REGS_PARM1' is invalid in C99 [-Wimplicit-function-declaration]
    u32 fd = PT_REGS_PARM1(regs);
             ^
writeblocker.bpf.c:30:17: warning: implicit declaration of function 'PT_REGS_PARM3' is invalid in C99 [-Wimplicit-function-declaration]
    u32 count = PT_REGS_PARM3(regs);
                ^
2 warnings generated.
  GEN-SKEL .output/sudoadd.skel.h
  CC       .output/sudoadd.o
  GEN-SKEL .output/writeblocker.skel.h
libbpf: failed to find BTF for extern 'PT_REGS_PARM1': -2
Error: failed to open BPF object file: No such file or directory
make: *** [Makefile:68: .output/writeblocker.skel.h] Error 254
make: *** Deleting file '.output/writeblocker.skel.h'
make: *** Waiting for unfinished jobs....
textreplace2.bpf.c:115:67: warning: implicit declaration of function 'PT_REGS_PARM2' is invalid in C99 [-Wimplicit-function-declaration]
    bpf_probe_read_user(&check_filename, FILENAME_LEN_MAX, (void*)PT_REGS_PARM2(regs));
                                                                  ^
textreplace2.bpf.c:115:60: warning: cast to 'void *' from smaller integer type 'int' [-Wint-to-void-pointer-cast]
    bpf_probe_read_user(&check_filename, FILENAME_LEN_MAX, (void*)PT_REGS_PARM2(regs));
                                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~
textreplace2.bpf.c:164:37: warning: implicit declaration of function 'PT_REGS_PARM1' is invalid in C99 [-Wimplicit-function-declaration]
    unsigned int fd = (unsigned int)PT_REGS_PARM1(regs);
                                    ^
textreplace2.bpf.c:170:35: warning: implicit declaration of function 'PT_REGS_PARM2' is invalid in C99 [-Wimplicit-function-declaration]
    long unsigned int buff_addr = PT_REGS_PARM2(regs);
                                  ^
textreplace2.bpf.c:174:32: warning: implicit declaration of function 'PT_REGS_PARM3' is invalid in C99 [-Wimplicit-function-declaration]
    size_t buff_size = (size_t)PT_REGS_PARM3(regs);
                               ^
5 warnings generated.

This project is great. Hello, if you want to compile samples for the ARM64 platform, what is the recommended environment to use?

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.