I. Basics
1. What are LKMs
2. What are Syscalls
3. What is the Kernel-Symbol-Table
4. How to transform Kernel to User Space Memory
5. Ways to use user space like functions
6. List of daily needed Kernelspace Functions
7. What is the Kernel-Daemon
8. Creating your own Devices
II. Fun & Profit
1. How to intercept Syscalls
2. Interesting Syscalls to Intercept
III. Soltutions (for admins)
1. LKM Detector Theory & Ideas
IV. Some Better Ideas (for hackers)
1. Tricks to beat admin LKMs
2. Patching the whole kernel - or creating the Hacker-OS
V. The near future : Kernel 2.2
1. Main Difference for LKM writer's
VI. Last Words
1. The 'LKM story' or 'how to make a system plug & hack compatible'
2. Links to other Resources
Appendix
A - Source Codes
The use of Linux in server environments is growing from second to second. So
hacking Linux becomes more interesting every day. One of the best techniques to
attack a Linux system is using kernel code. Due to its feature called Loadable
Kernel Modules (LKMs) it is possible to write code running in kernel space, which
allows us to access very sensitive parts of the OS. There were some texts and
files concerning LKM hacking before (Phrack, for example) which were very good.
They introduced new ideas, new methodes and complete LKMs doing anything a
hacker ever dreamed of. Also some public discussion (Newsgroups, Mailinglists)
in 1998 were very interesting.
So why do I write again a text about LKMs. Well there are several reasons :
systemcall | description |
---|---|
int sys_brk(unsigned long new_brk); | changes the size of used DS (data segment) ->this systemcall will be discussed in I.4 |
int sys_fork(struct pt_regs regs); | systemcall for the well-know fork() function in user space |
int sys_getuid
() int sys_setuid (uid_t uid) ... |
systemcalls for managing UID etc. |
int sys_get_kernel_sysms(struct kernel_sym *table) | systemcall for accessing the kernel system table (-> I.3) |
int sys_sethostname
(char *name,
int len); int sys_gethostname (char *name, int len); |
sys_sethostname is responsible for setting the hostname, and sys_gethostname for retrieving it |
int sys_chdir
(const char *path); int sys_fchdir (unsigned int fd); |
both function are used for setting the current directory (cd ...) |
int sys_chmod
(const char
*filename, mode_t
mode); int sys_chown (const char *filename, mode_t mode); int sys_fchmod (unsigned int fildes, mode_t mode); int sys_fchown (unsigned int fildes, mode_t mode); |
functions for managing permissions and so on |
int sys_chroot (const char *filename); | sets root directory for calling process |
int sys_execve (struct pt_regs regs); | important systemcall -> it is responsible for executing file (pt_regs is the register stack) |
long sys_fcntl (unsigned int fd, unsigned int cmd, unsigned long arg); | changing characteristics of fd (opened file descr.) |
int sys_link
(const char *oldname,
const char *newname); int sym_link (const char *oldname, const char *newname); int sys_unlink (const char *name); |
systemcalls for hard- / softlinks management |
int sys_rename (const char *oldname, const char *newname); | file renaming |
int sys_rmdir
(const char* name); int sys_mkdir (const *char filename, int mode); |
creating & removing directories |
int sys_open
(const char *filename,
int mode); int sys_close (unsigned int fd); |
everything concering opening files (also creation), and also closing them |
int sys_read
(unsigned int fd,
char *buf, unsigned int
count); int sys_write (unsigned int fd, char *buf, unsigned int count); |
systemcalls for writing & reading from Files |
int sys_getdents (unsigned int fd, struct dirent *dirent, unsigned int count); | systemcall which retrievs file listing (ls ... command) |
int sys_readlink (const char *path, char *buf, int bufsize); | reading symbolic links |
int sys_selectt (int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp); | multiplexing of I/O operations |
sys_socketcall (int call, unsigned long args); | socket functions |
unsigned long
sys_create_module
(char *name, unsigned
long size); int sys_delete_module (char *name); int sys_query_module (const char *name, int which, void *buf, size_t bufsize, size_t *ret); |
used for loading / unloading LKMs and querying |
function/macro | description |
---|---|
int sprintf
(char *buf,
const char *fmt,
...); int vsprintf (char *buf, const char *fmt, va_list args); |
functions for packing data into strings |
printk (...) | the same as printf in user space |
void *memset
(void *s, char c,
size_t count); void *memcpy (void *dest, const void *src, size_t count); char *bcopy (const char *src, char *dest, int count); void *memmove (void *dest, const void *src, size_t count); int memcmp (const void *cs, const void *ct, size_t count); void *memscan (void *addr, unsigned char c, size_t size); |
memory functions |
int register_symtab (struct symbol_table *intab); | see I.1 |
char *strcpy
(char *dest, const char
*src); char *strncpy (char *dest, const char *src, size_t count); char *strcat (char *dest, const char *src); char *strncat (char *dest, const char *src, size_t count); int strcmp (const char *cs, const char *ct); int strncmp (const char *cs,const char *ct, size_t count); char *strchr (const char *s, char c); size_t strlen (const char *s); size_t strnlen (const char *s, size_t count); size_t strspn (const char *s, const char *accept); char *strpbrk (const char *cs, const char *ct); char *strtok (char *s, const char *ct); |
string compare functions etc. |
unsigned long simple_strtoul (const char *cp, char **endp, unsigned int base); | converting strings to number |
get_user_byte
(addr); put_user_byte (x, addr); get_user_word (addr); put_user_word (x, addr); get_user_long (addr); put_user_long (x, addr); |
functions for accessing user memory |
suser(); fsuser(); |
checking for SuperUser rights |
int register_chrdev
(unsigned int major,
const char *name,
struct file_o perations
*fops); int unregister_chrdev (unsigned int major, const char *name); int register_blkdev (unsigned int major, const char *name, struct file_o perations *fops); int unregister_blkdev (unsigned int major, const char *name); |
functions which register device driver ..._chrdev -> character devices ..._blkdev -> block devices |
function | description | |
---|---|---|
int sprintf
(char *buf,
const char *fmt,
...); int vsprintf (char *buf, const char *fmt, va_list args); |
functions for packing data into strings | |
int request_module (const char *name); | says kerneld that the kernel requires a certain module (given a name or gerneric ID / name) | |
int release_module (const char* name, int waitflag); | unload a module | |
int delayed_release_module (const char *name); | delayed unload | |
int cancel_release_module (const char *name); | cancels a call of delayed_release_module | |