When I was developing RNAT I needed to change one kernel function (ip_options_compile), but I didn’t want the users to recompile their kernels. So then I discovered here that it was possible to hijack a kernel function by using a kernel module, and it solved my problem for that moment.
To exemplify the hijacking process, the code below shows how to hijack sys_mkdir() system call, preventing any user from creating a directory.
Don’t forget to change the old_sys_mkdir pointer to your real sys_mkdir() function.
——————- newmkdir.c —————-
static spinlock_t kern_lock = SPIN_LOCK_UNLOCKED;
unsigned long slock_flags;
#define LOCK_KERN spin_lock_irqsave(&kern_lock, slock_flags)
#define UNLOCK_KERN spin_unlock_irqrestore(&kern_lock, slock_flags)
static unsigned char pr_jump=”\xbf\x00\x00\x00\x00″ /* mov $0,%edi */
“\xff\xe7”; /* jmp *%edi */
static unsigned char pr_save;
unsigned char * old_sys_mkdir = (unsigned char *) 0xc01c79d0; /* grep sys_mkdir$ /proc/kallsyms */
/* function prototype from /usr/include/linux/syscalls.h */
asmlinkage long new_sys_mkdir(const char __user *pathname, int mode)
printk(“Tried to create: %s, mode: %d\n”, pathname, mode);
/* return Access Denied */
static int __init new_sys_mkdir_init(void)
/* fill pr_jump zero’s with the pointer to our new_sys_mkdir() */
*(long *)&pr_jump = (long)new_sys_mkdir;
/* replace the inital 7 bytes from the original sys_mkdir() with our jump to new_sys_mkdir() */
memcpy(pr_save, old_sys_mkdir, 7);
memcpy(old_sys_mkdir, pr_jump, 7);
static void __exit new_sys_mkdir_exit(void)
/* copy the old initial 7 bytes back */
memcpy(old_sys_mkdir, pr_save, 7);
——————– Makefile —————-
obj-m := newmkdir.o
KDIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
So probably I’ll be there (Criciúma) trying to explain in 15 minutes the RNAT project. Wow!
Here I am again to show you another stuff which I’ve been spending some time to develop. The RNAT, or Routable NAT.
This post is just an introduction to the RNAT project, since it is a very long subject.
Summarizing, I’ve started the RNAT development about one year ago. The main purpose was use it as my graduation final project. But after the presentation I realized that I could keep the project alive and turn it into a real and useful thing.
The real RNAT goal is to provide direct communication between hosts which are behind NAted networks by using two IP’s instead one. Like people say, one image is better than one thousand words:
[root@localhost ping]# ./ping usage: ping [-LRdfnqrv] [-c count] [-i wait] [-l preload] [-p pattern] [-s packetsize] [-t ttl] [-I interface address] [-a RNAT Address] host
[root@localhost ping]# ./ping 188.8.131.52 -a 10.0.4.143 PING 184.108.40.206 (220.127.116.11 10.0.4.143): 56 octets data 64 octets from 18.104.22.168 - 10.0.4.143: icmp_seq=0 ttl=63 time=96.9 ms 64 octets from 22.214.171.124 - 10.0.4.143: icmp_seq=1 ttl=63 time=52.7 ms 64 octets from 126.96.36.199 - 10.0.4.143: icmp_seq=2 ttl=63 time=49.8 ms 64 octets from 188.8.131.52 - 10.0.4.143: icmp_seq=3 ttl=63 time=41.9 ms --- 184.108.40.206 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 41.9/60.3/96.9 ms [root@localhost ping]#
It is just a small piece of the RNAT project. To get more information visit the official project site.