|
http://kerneltrap.org/node/17083 http://www.l0t3k.org/biblio/kernel/english/kernel-hijack.txt
hijacking of network subsystem functionApril
19, 2009 - 5:00am
Hi all, guys! In the attach you
can find the sample code, that is not working for me
#ifndef __KERNEL__ #define __KERNEL__ #endif #ifndef LINUX #define LINUX #endif #ifndef KERNEL #define KERNEL #endif #include <linux/kernel.h> #include <linux/module.h> #include <linux/netfilter_ipv4.h> #include <linux/ip.h> #include <linux/types.h> #include <linux/smp_lock.h> #include <net/ip_fib.h> #include <linux/inetdevice.h> #include <asm/uaccess.h> #include <asm/page.h> #include <net/ip.h>
#define CODESIZE 10
static char original_code[CODESIZE];
static char jump_code[CODESIZE] =
"\xb8\x00\x00\x00\x00" /* movl $0,%eax */
"\x40" /* inc %eax */
"\x90" /* nop */
"\x48" /* dec %eax */
"\xff\xe0" /* jmp *%eax */
;
// spinlock
static spinlock_t hijack_lock = SPIN_LOCK_UNLOCKED;
#define HIJACK_LOCK spin_lock_irqsave(&hijack_lock, sl_flags)
#define HIJACK_UNLOCK spin_unlock_irqrestore(&hijack_lock, sl_flags)
// function to intercept
static int (*addr) (struct sk_buff * skb);
// interceptor function
static int interceptor(struct sk_buff *skb);
void *_memcpy(void *dest, const void *src, int size)
{
const char *p = src;
char *q = dest;
int i;
for (i = 0; i < size; i++)
*q++ = *p++;
return dest;
}
//
// set interceptor
//
unsigned int mk_interceptor(void)
{
int sl_flags;
printk("setting interceptors...");
printk(KERN_INFO" page offset (%08x), addr=(%08x)\n", (unsigned int) PAGE_OFFSET, (unsigned int)addr);
if ((unsigned int) addr == 0 || (unsigned int) addr < PAGE_OFFSET)
{
printk("address for function is not valid (%08x)\n", (unsigned int)addr);
return -EINVAL;
}
*(long *)&jump_code[1] = (long)interceptor;
HIJACK_LOCK;
_memcpy(original_code, addr, CODESIZE);
_memcpy(addr, jump_code, CODESIZE);
HIJACK_UNLOCK;
return 0;
}
//
// remove interceptor
//
void rm_interceptor(void)
{
printk("removing interceptors...");
lock_kernel();
_memcpy(addr, original_code, CODESIZE);
unlock_kernel();
printk("OK\n");
}
//
// entry point
//
int __init startup_module(void)
{
int ret = 0;
printk("loading module...");
ret = mk_interceptor();
if (ret) goto init_error;
printk("OK\n");
return 0;
init_error:
printk("FAILED, ret= %d\n", ret);
return ret;
}
void exit_module(void)
{
printk("unloading cc_sender module...");
rm_interceptor();
printk("OK\n");
}
int interceptor(struct sk_buff * skb)
{
int ret = 0;
int sl_flags;
printk("interceptor\n");
HIJACK_LOCK;
_memcpy(addr, original_code, CODESIZE);
ret = addr(skb);
_memcpy(addr, jump_code, CODESIZE);
HIJACK_UNLOCK;
return ret;
}
module_init(startup_module);
module_exit(exit_module);
module_param(addr, long, 0);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eugeny Dudin");
MODULE_DESCRIPTION("covert channel sender");
obj-m:=hijack_test.o
FUNC_ADDRESS=0x$(word 1,$(shell grep ' ip_finish_output' /proc/kallsyms | awk '{print $1}'))
EXTRA_CFLAGS=-DFUNC_ADDRESS=$(FUNC_ADDRESS)
KDIR=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
install:
/sbin/insmod hijack_test.ko addr=$(FUNC_ADDRESS)
@echo module inserted OK
uninstall:
/sbin/rmmod hijack_test
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
|
