<!DOCTYPE Article PUBLIC "-//GNOME//DTD DocBook PNG Variant V1.1//EN"[
<!ENTITY version "1.0">
        <!-- replace version above with actual application version number-->
        <!--  Template Version: 1.0.1  (do not remove this line) -->
]>

<!-- =============Document Header ============================= -->

<article id="index"> <!-- please do not change the id -->

  <artheader>
    <title>Linux Kernel Rootkits</title>
    <copyright>
      <year>2002</year>
      <holder>Rainer Wichmann</holder>
    </copyright>

  <!-- translators: uncomment this:

  <copyright>
   <year>2000</year>
   <holder>ME-THE-TRANSLATOR (Latin translation)</holder>
  </copyright>

   -->

  <!-- do not put authorname in the header except in copyright - use
  section "authors" below -->

    <legalnotice>
      <para>
        Permission is granted to copy, distribute and/or modify this
        document under the terms of the <citetitle>GNU Free
        Documentation License</citetitle>, Version 1.1 or any later
        version published by the Free Software Foundation with no
        Invariant Sections, no Front-Cover Texts, and no Back-Cover
        Texts. You may obtain a copy of the <citetitle>GNU Free
        Documentation License</citetitle> from the Free Software
        Foundation by visiting <ulink type="http"
        url="http://www.fsf.org">their Web site</ulink> or by writing
        to: Free Software Foundation, Inc., 59 Temple Place - Suite
        330, Boston, MA 02111-1307, USA.
      </para>
    </legalnotice>

  <!-- this is the version of manual, not application -->
    <releaseinfo>
       This is version 1.0 of the Linux Kernel Rootkits paper. 
    </releaseinfo>

  </artheader>

 <!-- ============= Document Body ============================= -->

 <!-- ============= Introduction ============================== -->

  <sect1 id="intro">
    <title>Introduction</title>

    <para>
    After a succesful intrusion into a system, usually the intruder
    will install a so-called &quot;rootkit&quot; to secure further
    access. Such rootkits are readily available on the net and
    are designed to be used even by less experienced users.
    </para>
    <para>
    Rootkits usually
    comprise tools to erase traces of the intrusion from audit logs,
    &quot;backdoors&quot; that allow easy access, once installed,
    and means to hide the rootkit itself from administrators (such
    as, e.g., a modified executables of 'ps' and 'ls' that will hide 
    processes and files of the rootkit. Advanced rootkits will install 
    such modified executables
    with the same sizes and timestamps as the original
    ones (which is quite easy - any executable can be padded to a larger
    size by simply adding random junk at the end), and also with the same
    CRC checksum (which also can be adjusted).
    </para>
    <para>
    To detect such rootkits, it is necessary to have a database of
    <emphasis>cryptographic checksums</emphasis> of critical files, and compare
    these against the actual files. 
    Useful <emphasis>cryptographic checksums</emphasis>
    include MD5, SHA-1, TIGER (but not CRC, which can be faked). 
    </para>

    <para>
    Any application program is controlled by the 
    <emphasis>kernel</emphasis>, and any
    system access (such as writing to/reading from the disk) is performed
    by the kernel. The application will call a 
    <emphasis>kernel syscall</emphasis>,
    and the kernel will do the work and deliver the result back
    to the application. 
    From a users viewpoint,
    these syscalls are the lowest level of system functions, and provide
    access to filesystems, network connections, and other goodies.
    By modifying kernel syscalls, kernel rootkits can hide files,
    directories, processes, or network connections without modifying any
    system binaries. Obviously, checksums to confirm the integrity of a system
    are useless in this situation.
    </para>

     <sect2 id="about">
      <title>About This Document</title>
    
      <para>
     This document was written in DocBook(SGML). The
       <ulink type="http"
        url="http://www.la-samhna.de/library/rootkits/rootkits.sgml">SGML source</ulink> is available online.
     You can use the source to create other formats including
     PostScript, and PDF.
     </para>
      <para>
        Permission is granted to copy, distribute and/or modify this
        document under the terms of the <citetitle>GNU Free
        Documentation License</citetitle>, Version 1.1 or any later
        version published by the Free Software Foundation with no
        Invariant Sections, no Front-Cover Texts, and no Back-Cover
        Texts. You may obtain a copy of the <citetitle>GNU Free
        Documentation License</citetitle> from the Free Software
        Foundation by visiting <ulink type="http"
        url="http://www.fsf.org">their Web site</ulink> or by writing
        to: Free Software Foundation, Inc., 59 Temple Place - Suite
        330, Boston, MA 02111-1307, USA.
      </para>
     <para>
     You can reach the author at rwichmann {at} la-samhna.de. 
     </para>
    </sect2>
</sect1>    


 <!-- ============= Basics ============================== -->

  <sect1 id="basics">
    <title>The basics</title>

  <sect2 id="subvert">
    <title>Subverting the kernel</title>

  <para>
  There are basically two ways how a rootkit can subvert the kernel
  to perform actions on behalf of an intruder:
  <para>

  <variablelist>
       <varlistentry>
         <term>Loading a kernel module</term> 
	 <listitem><para>
	 The Linux kernel (and many other operating systems) can load
	 kernel modules (e.g. device drivers) at runtime. This allows
	 an intruder to insert a module that overrides kernel
	 syscalls in order to return incorrect values (e.g. does not list
	 certain files), or provides new functions useful for an
	 intruder (e.g. give root privileges to certain processes).
	 </para>
	 <para>
	 It is possible to compile a kernel where the interface for
	 loadable kernel modules is disabled.
	 </para>
	 </listitem>
       </varlistentry>

       <varlistentry>
         <term>Writing to /dev/kmem</term> 
	 <listitem><para>
	 The special device <filename>/dev/kmem</filename> is basically
	 a device that gives access to the memory region occupied by
	 the running kernel. By writing to 
	 <filename>/dev/kmem</filename> it is possible to overwrite
	 the kernel at runtime, and thus perform any arbitrary modification.
	 The only problem may be to find the correct location in
	 <filename>/dev/kmem</filename>, if one wants to overwrite
	 some particular part of the kernel. However, this is usually
	 a solveable problem.
	 </para>
	 <para>
	 Access to <filename>/dev/kmem</filename> can only be denied
	 by patching the kernel. A patch to make 
	 <filename>/dev/kmem</filename> 
	 non-writeable has been
	 published in Phrack issue 58, article 0x07 
	 (&quot;Linux on-the-fly kernel patching without LKM&quot;, 
	 by sd & devik).
	 As noted in a 
	 <ulink type="http" 
	 url="http://online.securityfocus.com/archive/1/273002">bugtraq 
	 post</ulink> by Guillaume Pellat, this patch still allows to
	 write to <filename>/dev/kmem</filename> by using mmap() rather
	 than direct file I/O.
	 </para>
	 </listitem>
  </variablelist>
  </sect2>

  <sect2 id="flow">
    <title>Suitable places in the flow of execution</title>


  <para>
  When a system call (e.g. open() to open a file) is made by
  an application, the flow of control looks like this:
  </para>

  <para><orderedlist>
  <listitem>
   <para>
    An interrupt is triggered, and execution continues at the interrupt
    handler defined for that interrupt. On Linux, interrupt 80 is used.
   </para>
   <para>
    A rootkit could replace the kernels interrupt handler by an own
    function. This requires a modification of the Interrupt Descriptor
    Table (IDT). A discussion of this method, as well as proof-of-cocept
    code, is published in Phrack issue 59, article 0x04
    (&quot;Handling the Interrupt Descriptor Table&quot;, by kad). This article
    also provides source code for a utility <application>CheckIDT</application>
    that can be used to list the IDT and save the current state to 
    check its integrity later on.
   </para>
  </listitem>

  <listitem>
   <para>
    The interrupt handler (named system_call() on Linux) 
    looks up the address of the requested syscall
    in the syscall table, and executes a jump to the respective address.
   </para>
   <para>
    A rootkit may (a) modify the interrupt handler to use a (rootkit-supplied)
    different syscall table, or (b) modify the entries in the syscall table to
    point to the rootkits replacement functions.
   </para>
   <para>
    Method (a) is currently used by one rootkit only, 
    the SucKIT rootkit presented in
    Phrack issue 58, article 0x07 
    (&quot;Linux on-the-fly kernel patching without LKM&quot;, by sd & devik). 
    This is a fully working rootkit that is loaded through 
    <filename>/dev/kmem</filename> (i.e. it does not need a kernel with
    support for loadable kernel modules. It provides 
    a password protected remote access connect-back shell
    initiated by a spoofed packet (bypassing most of firewall
    configurations),
    and can hide processes, files and connections.
   </para>
   <para>
    Method (b) is used by a large number of rootkits, because it is very
    easy to code. For a list of these rootkits, see <xref linkend="list" />.
   </para>
  </listitem>

  <listitem>
   <para>
    The syscall function is executed, and control returns to the application.
   </para>
   <para>
    A rootkit may overwrite the syscall function to place a jump to its 
    own replacement function at the start of the syscall function.
   </para>
   <para>
    No currently known rootkit uses this method.
   </para>
  </listitem>
  </orderedlist></para>

  </sect2>
  </sect1>

  <sect1 id="list">
    <title>List of Kernel Rootkits</title>

  <sect2 id="kmem">
    <title>Rootkits loaded via /dev/kmem</title>
  <para>
    <emphasis>SucKIT</emphasis> is a rootkit presented in
    Phrack issue 58, article 0x07 
    (&quot;Linux on-the-fly kernel patching without LKM&quot;, by sd & devik). 
    This is a fully working rootkit that is loaded through 
    <filename>/dev/kmem</filename> (i.e. it does not need a kernel with
    support for loadable kernel modules. It provides 
    a password protected remote access connect-back shell
    initiated by a spoofed packet (bypassing most of firewall
    configurations),
    and can hide processes, files and connections.
   </para>

  </sect2>

  <sect2 id="lkm">
    <title>Loadable Kernel Modules</title>

  <para>
  Except for the SucKIT rootkit, all
  published rootkits are LKM rootkits and 
  use the method of syscall table modification (see <xref linkend="flow" />).
  The following list provides an overview of these rootkits.
  </para>
   <para>
   <emphasis>Rial</emphasis> by techno[k] (technok at pkcrew dot org)
   hides files, file parts, and connections. 
   No backdoor
   is provided. 
   Hiding of file parts is buggy, <command>less</command> will hang.
   RIAL does not hide itself (use <command>lsmod</command> 
   or <command>cat /proc/modules</command> to detect). 
   </para>
   <para>
   <emphasis>heroin</emphasis> by Runar Jensen (zarq at opaque dot org)
   hides files and processes. No backdoor
   is provided. Cannot be removed with <command>rmmod</command>, and
   tries to hide itself, but can be found by
   </para>
    <screen>
    <prompt>bash$ </prompt><userinput>cat /proc/ksyms | grep heroin</userinput>
    </screen>
   <para>
   <emphasis>afhrm</emphasis> by Michal Zalewski 
   (lcamtuf at boss dot staszic dot waw dot pl)
   redirects (and hides) files. No backdoor
   is provided. Runs on 2.2 with some work, but file hiding
   seems to have bugs. 
   Can hide itself, but method appears to be inappropriate 
   for 2.2 kernels
   (results are rather suspicious).
   </para>
   <para>
   <emphasis>Synapsis (v. 0.4)</emphasis> by Berserker 
   (berserker dot ncl at infinito dot it) Hides files, processes, and users. 
   Gives root privileges 
   to a
   user with a pre-defined UID (default 666). 
   Hides ports. Can be controlled
   via <command>cat <replaceable>password command</replaceable></command>. 
   Hides itself from <command>lsmod</command>, but can be found by 
   <command>cat /proc/modules</command>. File hiding and control interface
   have bugs.
   </para>
   <para>
   <emphasis>adore</emphasis> by Stealth hides files, 
   processes, services, 
   and can execute a process 
   (e.g. /bin/sh) with 
   root privileges. Controlled with a helper program 
   <application>ava</application>.
   <application>Adore</application> hides itself, and cannot 
   be removed by <command>rmmod</command>.
   </para>
   <para>
   <emphasis>knark</emphasis> by Creed (creed at sekure dot net)
   hides files, processes, services, 
   redirect commands, 
   and can give  
   root privileges. <application>Creed</application> is 
   controlled with a set of helper programs, and
   can execute commands sent from a remote host. It
   hides itself and cannot
   be removed by <command>rmmod</command>.
   </para>
   <para>
   <emphasis>itf</emphasis> by plaguez (dube0866 at eurobretagne dot fr)
   has been published in Phrack issue 52. It hides files and 
   processes, redirect commands, hides the PROMISC
   flag (i.e. sniffers), 
   and can give root privileges. It installs a backdoor,
   hides itself and cannot be removed by <command>rmmod</command>.
   </para>
   <para>
   <emphasis>kis</emphasis> by optyx (optyx at uberhax0r dot net)
   is a client/server system to remotely control a machine, with a
   kernel rootkit as the server on the remotely controlled machine.
   It can hide processes, files, connections, redirect execution, and
   execute commands. It hides itself and can remove security modules
   already loaded.
   </para> 
  </sect2>
  </sect1>

 <!-- ============= Detecting ============================== -->

  <sect1 id="detect">
    <title>Detecting Kernel Rootkits</title>

    <para>
    To get a list of kernel modules, two standard methods can be used:
    </para>
    <screen>
    <prompt>bash$ </prompt><userinput>lsmod</userinput>
    <prompt>bash$ </prompt><userinput>cat /proc/modules</userinput>
    </screen> 
    <para>
    In addition, one can look at the list of symbols exported by
    modules (<filename>/proc/ksyms</filename>), 
    where the name of the corresponding
    module will be listed in square brackets, like the following symbol
    exported from the snd (sound) module:
    </para>
    <programlisting>
    c85029f4 snd_task_name  [snd]
    </programlisting>
    <para>
    Unfortunately, being a kernel module, an LKM rootkit can easily defeat
    such efforts by a variety of methods.
    Fortunately, there is a better
    way to detect an LKM rootkit:
    </para>
    <para>
    In order to replace kernel syscalls with their own code, LKM rootkits 
    modify the table which holds the addresses of these syscalls, to point
    to the module's replacement function instead of the original kernel 
    function.
    Now, whenever a kernel is compiled, a 
    <emphasis>map of kernel symbols</emphasis> 
    and their
    respective addresses in the kernel is generated. This map is called
    <filename>System.map</filename> 
    (sometimes with the kernel version appended), and
    usually install in the same location as the kernel 
    (e.g. <filename class="directory">/boot</filename>).
    Thus, a straightforward way to detect hijacked kernel syscalls is to
    compare this map against the actual addresses of all syscalls, which
    will show all syscalls whose address is different from the original
    address listed in the map.
    </para>

  <sect2 id="Programs">
    <title>Programs</title>

    <para>
    This is a non-exhaustive list of programs that are useful for
    the detection of kernel modifications in a running system.
    </para>

  <variablelist>
    <varlistentry>
    <term>kern_check.c</term> 
    <listitem>
    <para>
    <ulink type="http" 
    url="http://la-samhna.de/library/kern_check.c">kern_check.c</ulink>
    is a small command-line utility (for Linux 2.2.x, 2.4.x) that
    will compare your <filename>System.map</filename> 
    against your kernels syscall table 
    and warn
    about any inconsistencies 
    (<ulink type="http" 
    url="http://la-samhna.de/library/kern_check.c.asc">PGP signature 
    kern_check.c.asc</ulink>).
    </para> 
    <screen>
    <prompt>bash$ </prompt><userinput>gpg --verify kern_check.c.asc kern_check.c</userinput>
    <prompt>bash$ </prompt><userinput>gcc -O2 -Wall -o kern_check kern_check.c</userinput>
    <prompt>bash$ </prompt><userinput>su</userinput>
    <prompt>bash$ </prompt><userinput>kern_check <replaceable>/path/to/System.map</replaceable></userinput>
    </screen>
    <note>
    <title>NOTE</title>
    <para>
    This will only detect rootkits that modify the syscall table directly.
    In particular, it will not detect the SucKIT rootkit 
    (see <xref linkend="flow" />).
    </para>
    </note>
    </listitem>
    </varlistentry>
    <varlistentry>
    <term>CheckIDT</term> 
    <listitem>
    <para>
    CheckIDT, published in Phrack issue 59, article 0x04
    (&quot;Handling the Interrupt Descriptor Table&quot;, by kad) is 
    a utility 
    that can be used to list the Interrupt Descriptor Table (IDT)
    (see <xref linkend="flow" />) 
    and save the current state to 
    check its integrity later on. Currently there is no published 
    real rootkit that uses the IDT, only proof-of-concept code.
    </para>
    </listitem>
    </varlistentry>
    <varlistentry>
    <term>samhain</term> 
    <listitem>
    <para>
    <ulink type="http" 
    url="http://la-samhna.de/samhain/">samhain</ulink> is a file integrity
    checker that can also check for kernel integrity. 
    <application>samhain</application> performs checks 
    for <emphasis>all</emphasis>
    of the points discussed in <xref linkend="flow" />.
    </para>
    </listitem>
    </varlistentry>
  </variablelist>
  </sect2>

  </sect1>
</article>









