科技动态 | 硬件广场 | 下载基地 | 网络教室 | 网络冲浪 | 科学博览 | 移动时代 | 手机上网 | 桌面壁纸 | 科技商情 |
3.3 使你的程序不可以被跟踪(理论)
#include <sys/ptrace.h> int ptrace(int request, int pid, int addr, int data); 那我们如何控制strace呢?不要傻的认为将strace从你的系统中删去就可以让一切OK--正如我展示给你看的,ptrace(...)是一个库函数.每一个hacker可以编他自己的函数来做和strace一样的事情.因此我们需要一个好一些的安全的解决方法.你的第一个念头可能是搜索ptrace所用的系统调用;确实有一个系统调用来实现他.但是先让我们看看另一种方法. 记得在2.5.1 :我说过任务标志位.有两种标志位来代表被跟踪的进程.这是我们控制被跟踪的方法.只要拦截了sys_execve(...)系统调用,并且检查当前进程的那两个标志位就可以了. 3.3.1 一个反跟踪的实用例子
#define MODULE #define __KERNEL__ #include <linux/module.h> #include <linux/kernel.h> #include <asm/unistd.h> #include <sys/syscall.h> #include <sys/types.h> #include <asm/fcntl.h> #include <asm/errno.h> #include <linux/types.h> #include <linux/dirent.h> #include <sys/mman.h> #include <linux/string.h> #include <linux/fs.h> #include <linux/malloc.h> extern void* sys_call_table[]; int __NR_myexecve; int (*orig_execve) (const char *, const char *[], const char *[]); char *strncpy_fromfs(char *dest, const char *src, int n) { char *tmp = src; int compt = 0; do { dest[compt++] = __get_user(tmp++, 1); } while ((dest[compt - 1] != '\0') && (compt != n)); return dest; } int my_execve(const char *filename, const char *argv[], const char *envp[]) { long __res; __asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long) (filename)), "c"((long) (argv)), "d"((long) (envp))); return (int) __res; } int hacked_execve(const char *filename, const char *argv[], const char *envp[]) { int ret, tmp; unsigned long mmm; char *kfilename; /*检查标志位*/ if ((current->flags & PF_PTRACED)||(current->flags & PF_TRACESYS)) { /*我们被跟踪了,因此打印出跟踪我们的进程(程序名)并且返回.不执行*/ kfilename = (char *) kmalloc(256, GFP_KERNEL); (void) strncpy_fromfs(kfilename, filename, 255); printk("<1>TRACE ATTEMPT ON %s -> PERMISSION DENIED\n", kfilename); kfree(kfilename); return 0; } ret = my_execve(filename, argv, envp); return ret; } int init_module(void) /*初始化模块*/ { __NR_myexecve = 200; while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0) __NR_myexecve--; orig_execve = sys_call_table[SYS_execve]; if (__NR_myexecve != 0) { sys_call_table[__NR_myexecve] = orig_execve; sys_call_table[SYS_execve] = (void *) hacked_execve; } return 0; } void cleanup_module(void) /*卸载模块*/ { sys_call_table[SYS_execve]=orig_execve; } 这个LKM也纪录下任何有人想跟踪的可执行程序. OK,这个LKM检查一些标志位.但是如果你跟踪一个已经运行的程序呢?假设一个程序(shell或者其他的)正在运行,而且PID是1853.现在你做一个'strace -p 1853'.你会成功的.因此,为了保证这个也能安全.替换sys_ptrace(...)是仅有的方法.看下面的模块: #define MODULE #define __KERNEL__ #include <linux/module.h> #include <linux/kernel.h> #include <asm/unistd.h> #include <sys/syscall.h> #include <sys/types.h> #include <asm/fcntl.h> #include <asm/errno.h> #include <linux/types.h> #include <linux/dirent.h> #include <sys/mman.h> #include <linux/string.h> #include <linux/fs.h> #include <linux/malloc.h> extern void* sys_call_table[]; int (*orig_ptrace)(long request, long pid, long addr, long data); int hacked_ptrace(long request, long pid, long addr, long data) { printk("TRACING IS NOT ALLOWED\n"); return 0; } int init_module(void) /*初始化模块*/ { orig_ptrace=sys_call_table[SYS_ptrace]; sys_call_table[SYS_ptrace]=hacked_ptrace; return 0; } void cleanup_module(void) /*卸载模块*/ { sys_call_table[SYS_ptrace]=orig_ptrace; } 使用这个模块,就没有人可以跟踪了.
摘自《赛迪网》 pragmatic/THC,(版本1.0)/文
|
|
版权所有 中华网 |