china.com
主页
新闻
体育
游戏
文化
教育
健康
财经
科技
旅游
军事
娱乐
商贸
  科技动态 硬件广场 下载基地 网络教室 网络冲浪 科学博览 移动时代 手机上网 桌面壁纸 科技商情  


第三部分 解决方案(给系统管理员)


3.3 使你的程序不可以被跟踪(理论)


现在我们应该讨论一下如何让我们的可执行程序避免被跟踪了,正如我过去说的那样,strace是我们的一项工具,我介绍他来帮助我们看某一特定的程序到底使用了那些系统调用。另外一个strace的非常有意思的用法在TICK/THC中的'Human to Unxi Hacker'文件中介绍.他告诉我们如何使用strace进行TTY入侵.只要strace你的邻居的shell,你就会获得他的每一个输入.因此,系统管理员必须意识到strace的危险性.strace程序使用如下的API函数:

#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 一个反跟踪的实用例子


这是我的一个小的LKM,叫做'Anti-tracer'.他主要基于上面我们提到的思路.我们的进程的这个域可以很容易的通过使用当前进程的指针(任务指针)来得到.其他的就没有什么更新的了.

#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)/文

 


科技检索


中华网推荐

  • 1000名医生在线咨询

  • 中国足球队官方网站

  • 鸦片玫瑰(新版)

  • 精选股票天地

  • 闪光的flash教程

  • 中华网汽车世界

  • 为你的爱情出谋划策

  • 网文精选——野百合集

  • 世界文化遗产在中国

  • 历届香港小姐风姿集




  • 网络教室编辑信箱
    版权声明 | 本站检索 | 联系方法 | 刊登广告 | 使用说明 | 关于中华网 | 豁免条款

    版权所有 中华网