executing insmod hangs the entire os
When I execute insmod for the kernel module object file of the following C code, the entire system hangs. The module replaces the reference to original chroot system call with a new one in the sys_call_table. The syscall_table address is correct as per System.map(which returns 2 values for sys_call_table, surprisingly). I am on a VM running CentOS 6.6 with kernel version 2.6.32-504. #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/unistd.h> #include <asm/cacheflush.h> #include <asm/page.h> #include <asm/current.h> #include <linux/sched.h> #include <linux/kallsyms.h> unsigned long *syscall_table = (unsigned long *)0xffffffff81600560; asmlinkage int (*original_chroot)(const char __user *); asmlinkage int new_chroot(const char __user *filename){ printk(KERN_ALERT "CHROOT HIJACKED"); return (*original_chroot)(filename); } static int init(void) { printk(KERN_ALERT "\nHIJACK INIT\n"); original_chroot = (void *)syscall_table[__NR_chroot]; syscall_table[__NR_chroot] = new_chroot; return 0; } static void exit(void) { syscall_table[__NR_chroot] = original_chroot; printk(KERN_ALERT "MODULE EXIT\n"); } module_init(init); module_exit(exit);
On Tue, 17 Feb 2015 21:46:00 +0530, noyb noybee said:
am on a VM running CentOS 6.6 with kernel version 2.6.32-504.
Which probably has kernel relocation and ASLR enabled.
unsigned long *syscall_table = (unsigned long *)0xffffffff81600560;
So that isn't pointing at the syscall table in the running kernel.
syscall_table[__NR_chroot] = new_chroot;
So you just trashed an essentially random location in memory. You explained in a private email what you were trying to do here - and I'll point out that it essentially changes the kernel API in unexpected and undocumented ways. It even introduces some security holes and bugs (hint - if you close all file descriptors, what happens to programs that were expecting stdin/stdout/stderr to be open? In particular, programs that open, say, /dev/log so they have syslog output, and then chroot. Or programs that open a socket, then chroot and drop permissions (like openssh's sshd for privilege separation). You're really not doing yourself a favor with this whack-a-mole approach to security. You *really* need to sit down and think about what problem you're trying to solve here.
On Tue, Feb 17, 2015 at 11:59 PM, <Valdis.Kletnieks@vt.edu> wrote:
On Tue, 17 Feb 2015 21:46:00 +0530, noyb noybee said:
am on a VM running CentOS 6.6 with kernel version 2.6.32-504.
Which probably has kernel relocation and ASLR enabled.
unsigned long *syscall_table = (unsigned long *)0xffffffff81600560;
So that isn't pointing at the syscall table in the running kernel.
syscall_table[__NR_chroot] = new_chroot;
So you just trashed an essentially random location in memory.
Oh no, the memory location is retrieved dynamically every time the module is compiled and loaded. Also, I am just experimenting with hooking into system calls here. The project itself is not completed planned at the moment, like you pointed out.
On Tue, 17 Feb 2015 21:46:00 +0530, noyb noybee said:
am on a VM running CentOS 6.6 with kernel version 2.6.32-504.
Which probably has kernel relocation and ASLR enabled.
unsigned long *syscall_table = (unsigned long *)0xffffffff81600560;
So that isn't pointing at the syscall table in the running kernel.
syscall_table[__NR_chroot] = new_chroot;
Leave apart the security holes / undocumented ways etc. raised by Valdis, the way you are getting the address of the syscall table( from System.map), and then changing that will only hang the system. The syscall table is read only. You need to make it writable by changing the write protection bit in the Control Regs. Hope it helps. Thanks, Saumendra ::DISCLAIMER:: ---------------------------------------------------------------------------------------------------------------------------------------------------- The contents of this e-mail and any attachment(s) are confidential and intended for the named recipient(s) only. E-mail transmission is not guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or may contain viruses in transmission. The e mail and its contents (with or without referred errors) shall therefore not attach any liability on the originator or HCL or its affiliates. Views or opinions, if any, presented in this email are solely those of the author and may not necessarily reflect the views or opinions of HCL or its affiliates. Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of this message without the prior written consent of authorized representative of HCL is strictly prohibited. If you have received this email in error please delete it and notify the sender immediately. Before opening any email and/or attachments, please check them for viruses and other defects. ----------------------------------------------------------------------------------------------------------------------------------------------------
On Wed, Feb 18, 2015 at 12:16 PM, Saumendra Dash <saumendra.d@hcl.com> wrote:
On Tue, 17 Feb 2015 21:46:00 +0530, noyb noybee said: The syscall table is read only. You need to make it writable by changing the write protection bit in the Control Regs. Wasn't that implemented from version 3 and not 2.6?
participants (3)
-
noyb noybee -
Saumendra Dash -
Valdis.Kletnieks@vt.edu