Hijacking Linux kernel 2.6 sys_connect system call
In Linux-2.4.x kernel it was very simple create an lkm to hijack the sys_connect system call using the exported symbol:
1 | extern void *sys_call_table[]; |
So, it is very simple to substitute the pointer to another system call, the one we have created!
1 2 3 4 5 6 | static inline _syscall1(int,close,int,fd); int ( * o_socketcall) (int, unsigned long *); int my_socketcall (int, unsigned long *); o_socketcall = sys_call_table[SYS_socketcall]; //saving original pointer sys_call_table[SYS_socketcall] = (void *)my_socketcall; //hijacking system call sys_call_table[SYS_socketcall] = (void *)o_socketcall; //restoring original syscall |
( Read Phrack n.50 to learn more about system call hijacking in Linux-2.4.x kernels )
In Linux-2.6.x kernels the sys_call_table symbol is no more exported for security and stability reasons. So how can we hijack connections?Here is the solution I use in Kernel Socks Bouncer and it works very well!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //Use this to restore original conditions static int unpatch_unix_stream_connect(void) { if (unix_stream_ops && orig_unix_stream_connect) { unix_stream_ops->connect = orig_unix_stream_connect; return 0; } return -1; } //Use this to substitute your connect to the original static int patch_unix_stream_connect(void) { struct socket *sock_stream = NULL; if (sock_create(2, 1, 0, &sock_stream) < 0) return -1; if (sock_stream && (unix_stream_ops = sock_stream->ops)) { orig_unix_stream_connect = unix_stream_ops->connect; unix_stream_ops->connect = ksb26_unix_stream_connect; sock_release(sock_stream); } return 0; } |
This function causes the use of ksb26_unix_stream_connect instead of the real connect; as in 2.4 kernel we have to save the pointer to the original call and then we can push our call!


Nice buddy, I really appreciate your code which is very well.
Fredi