当前位置:Linux教程 - Linux - 在Linux可加载内核模块中探秘(8)

在Linux可加载内核模块中探秘(8)



         第二部分:趣味LKM
    第二章:如何寻找有用的系统调用
    作者:CoolBoy
    上一章我们谈到了怎样去捕获一个系统调用,那么我们现在怎么才知道哪些系统调用就是我们当前所需要捕获的呢?在浩繁的列表里,怎样才能找到那一行关键的系统调用代码?——也许你不是一个能玩转内核的“内核高手”,也不可能了解所有使用系统调用的函数如何工作,所以在此我可以给大家提供一些发现和了解系统调用的方法。

      a、读源代码。在象linux这样的系统上,你可以看到所有用户常用的一些命令的源代码,一当你发现了一 些基本的函数,例如dup,open,read,write,...就跳到步骤b。

      b、看看include/sys/syscall.h,试着去找到一个与此直接相关的系统调用(例如搜索dup,你会找到SYS_dup,搜索read,你会找到SYS_read),如果这样不行的话,跳到步骤c。

      c、有些函数调用的是同一个系统调用(前面提到过,象Socket的调用),这时你就需要看看include文件和相关的系统调用了。

      请大家一定要认识到,并非所有的C语言库函数都要用到系统调用,大多数C函数和系统调用是毫无关系的!一个稍有经验的黑客会回头去看看前面第二章提到的系统调用,那边提供出来的信息已经足够了。例如,很 显然用户的ID管理是通过系统调用uid-systemcalls来执行的。如果你想亲自确认一下,可以去看看库源代码(核心源代码)。

      对于一个黑客来讲,最为困难的问题在于,系统管理员往往会自己写一些测试系统安全性和完整性的程序,而这些程序的源代码黑客是看不到的。他们不可能知道这些程序如何运行,又调用了哪些系统调用,也就更不可能去捕获管理员使用的系统调用以达到隐藏自己的目的。甚至在有些情况下,系统管理员本身就可能使用自己写的LKM程序来测试其系统,(系统管理员通常也使用黑客手段来测试自己的系统)在这种情况下,黑客们将怎么办呢?

      ——他们将使用strace跟踪程序,从而找出其中有点“不对劲”的系统调用。

      strace的使用方法是在后面加命令行字符串,它能够对整个命令的执行步骤进行跟踪。

      假设大家知道超级管理员用来测试系统的程序名叫super_admin_prog(这可以用很多种方法来办到),所以下面我们运行strace。

      #strace super_admin_prog
      它将输出这个程序用到的所有系统调用,包括管理员所用来检测系统安全的LKM(如果有的话)。我这边   没有现成的可以用来演示的系统管理员的LKM程序输出结果,不过你可以看一看\strace whoami\的运行  结果(每一行都是一个系统调用):

      execve(\"/usr/bin/whoami\", [\"whoami\"], [/* 50 vars */]) = 0
      mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40007000
      mprotect(0x40000000, 20673, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
      mprotect(0x8048000, 6324, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
      stat(\"/etc/ld.so.cache\", {st_mode=S_IFREG|0644, st_size=13363, ...}) = 0

      ......

      read(3, \"root:x:0:0:root:/root:/bin/bash\\n\"..., 4096) = 1074
      close(3) = 0
      munmap(0x4000b000, 4096) = 0
      fstat(1, {st_mode=S_IFREG|0644, st_size=2798, ...}) = 0
      mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4000b000
      write(1, \"r00t\\n\", 5r00t ) = 5
      _exit(0) = ?

      这个列表列出了whoami程序执行过程中所用到的所有系统调用,其中包括四个十分有趣的调用,如果想对whoami的输出结果进行操纵,捕获这四个调用是必不可少的。

      geteuid() = 500
      getuid() = 500
      getgid() = 100
      getegid() = 100

      OK,详细的就不多谈了。体会一下上一章里那个禁止建立目录的程序,大家就会有更深刻的认识的。
    发布人:Crystal 来自:Linux专区