evolve or die

elfdoctor.c

elfdoctor.c
Posted Sep 6, 2003
Authored by Pluf

Scanner to look up infection techniques that can be used in ELF modules. Includes function hijacking, relocation files, etc. Runs on linux 2.4.X.

systems | linux
MD5 | db05d4c0327d757747a9d31ff7f6a0ac

elfdoctor.c

Change Mirror Download
/* 
* ELF infection methods scanner 0.1
* Coded by pluf (pluf@mail.ru)
*
* Use:
*
* ./scaner -v -f file_to_check
*
* file_to_check must be a ET_EXEC file
*
* It runs on linux2.4.X
*
* Infection methods supported:
* + text segment infection (padding), data segment infection, or other kind of
* methods that change the real entry point of infected file.
* + altplt function hijacking method
* + dynamic section infection to allow add a new library dependance and make
* easy functions hijacking
* + plt infection and got redirection too allow funtion hijacking
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <elf.h>

int verbose = 0;
unsigned short infected = 0x0000;

struct {
int size;
int vaddr;
int offset;
} section_inf[5];

#define A 0x0001
#define B 0x0020
#define C 0x0100
#define D 0x0200

void
show_method(type)
int type;
{
printf("\n [ Results ]\n");
if (infected & B) printf(" [+] Posible text or data segment infection: entry point dont' referer text segment\n");
if (infected & C) printf(" [+] ALTPLT function hijacking method.\n");
if (infected & D) printf(" [+] Dynamic section infected: posible DT_NEEDED symbol injected instead of orig DT_DEBUG\n");
if (infected & A) printf(" [+] PLT infection and got redirection\n");
printf("\n");

}

int
check_fake_entry(orig_entry)
int orig_entry;
{
if (orig_entry != section_inf[4].vaddr) return (1);
return (0);
}

int
check_function_hijacking(shnum, string, shdr)
int shnum;
const char *string;
Elf32_Shdr *shdr;
{
Elf32_Shdr *shdrp = shdr;
register int i;

for (i = 0; i < shnum; i++) {
if (!strcmp(&string[shdrp->sh_name], ".orig.plt")) return (1);
++shdrp;
}

return (0);
}

int
check_dynamic_infection(len, dyn)
int len;
Elf32_Dyn *dyn;
{
register int i;

for (i = 0; i < (len/sizeof(Elf32_Dyn)); i++) {
if (dyn->d_tag == DT_DEBUG)
return (0);
++dyn;
}

return (1);
}

int
find_symbol(long got_entry, Elf32_Sym *dynsym, char *dynstr)
{
register int i;
int syndym_entries = (section_inf[1].size/sizeof(Elf32_Sym));
int gotp;

gotp = got_entry;

for (i = 0; i < syndym_entries; i++) {
if (dynsym->st_value != 0) {
if (dynsym->st_value == (gotp -= 0x06) ||
dynsym->st_value == (gotp -= 16)) {
if(verbose)
printf(" [%3.5d] %-50.60s (plt-entry -> 0x%.7x) = [ok]\n",
i, &dynstr[dynsym->st_name], dynsym->st_value);
return (1);
}
}
gotp = got_entry;
++dynsym;
}

if (verbose)
printf(" [%c] %-50.60s (plt->entry -> 0x%.7x) = [Bad]\n", '?', &dynstr[dynsym->st_name], dynsym->st_value);
return (0);
}

int
check_plt_infection(Elf32_Sym *dynsym, char *got, char *dynstr)
{
register int i;
Elf32_Sym *dynsymp = dynsym;
char *ptr = got;
long *addr;
int got_entries = (section_inf[0].size/4), bad_entry = 0;

if(verbose)
printf("\n [ Checking for valid dynamic symbols ]\n\n");

addr = (long*)ptr;
for (i = 2, addr+=2; i < got_entries; i++) {
if (*addr != 0)
if (!find_symbol(*addr, dynsymp, dynstr)) ++bad_entry;
++addr;
}

return (bad_entry);
}

char *get_section(Elf32_Shdr *shdr,
char *sdata,
int shnum,
int fd,
const char *string_table,
const char *section_name,
unsigned char id)
{
Elf32_Shdr *shdrp = shdr;
register int i;
int offset;
int size;
int vaddr;
char *buf;

shdrp = (Elf32_Shdr*)sdata;
for (i = 0; i < shnum; i++) {
if (!strcmp(&string_table[shdrp->sh_name], section_name)) {
section_inf[id].offset = shdrp->sh_offset;
section_inf[id].size = shdrp->sh_size;
section_inf[id].vaddr = shdrp->sh_addr;

offset = shdrp->sh_offset;
size = shdrp->sh_size;
vaddr = shdrp->sh_addr;
if (verbose)
printf(" [!] %-12s addr(0x%x) offset(0x%.8x) size(0x%.8x)\n", section_name,
vaddr,offset,size);
}
++shdrp;
}

buf = (char*)malloc(size);
if (buf == NULL) {
perror("malloc");
exit(-1);
}
if (lseek(fd, offset, SEEK_SET) < 0) {
perror("lseek");
exit(-1);
}
if (read(fd, buf, size) != size) {
perror("read");
exit(-1);
}

return (buf);
}

void
help()
{
printf("usage: ./scanner -v -f file\n\n");
exit(-1);
}

int
main(argc, argv)
int argc;
char *argv[];
{
Elf32_Ehdr elf_header;
Elf32_Phdr *phdr;
Elf32_Shdr *shdr, *strtable;
Elf32_Dyn *dynamic;
Elf32_Sym *dynsym;
char *pdata, *sdata, *string, *got, *dynstr, *text;
int shlen, phlen;
char *file;
int fd, op;

printf("\n\n\t--=== Elf infections scanner v0.1 by pluf ==--\n\n");

while ((op=getopt(argc, argv, "vf:")) != -1) {
switch(op) {
case 'v':
verbose +=1;
break;
case 'f':
if (strlen(optarg) > 256)
exit(-1);
file = optarg;
break;
case '?':
case 'h':
default:
help();
}
}

if (argc < 3)
help();

/* open file */
if ((fd = open(file, O_RDONLY)) == -1) { perror("open");exit(-1); }

/*get elf */
if (read(fd, &elf_header, sizeof(elf_header)) < 0) { perror("read");exit(-1); }

/* get program header table */
pdata = (char*)malloc(phlen = sizeof(*phdr)*elf_header.e_phnum);
if (lseek(fd, elf_header.e_phoff, SEEK_SET) <0 ) { perror("lseek");exit(-1); }
if (read(fd, pdata, phlen) < phlen) { perror("read");exit(-1); }

/* get section header table */
sdata = (char*)malloc(shlen = sizeof(*shdr)*elf_header.e_shnum);
if (lseek(fd, elf_header.e_shoff, SEEK_SET) < 0) { perror("lseek");exit(-1); }
if (read(fd, sdata, shlen) < shlen) { perror("read");exit(-1); }
shdr = (Elf32_Shdr*)sdata;

/* get string table */
strtable = &((Elf32_Shdr *)sdata)[elf_header.e_shstrndx];
string = (char*)malloc(strtable->sh_size);
if (string == NULL) { perror("malloc");exit(-1); }
if (lseek(fd, strtable->sh_offset, SEEK_SET) < 0) { perror("lseek");exit(-1); }
if (read(fd, string, strtable->sh_size) != strtable->sh_size) { perror("read");exit(-1); }

if(verbose)
printf(" [ Loading needed sections ]\n\n");

/* get dynamic symbol table (.dynsym section) */
dynsym = (Elf32_Sym*)get_section(shdr, sdata, elf_header.e_shnum, fd, string, ".dynsym",1);

/* get dynamic symbol string table (.dynstr section) */
dynstr = get_section(shdr, sdata, elf_header.e_shnum, fd, string, ".dynstr", 2);

/* get .text section */
text = get_section(shdr, sdata, elf_header.e_shnum, fd, string, ".text",4);

/* get .dynamic section */
dynamic = (Elf32_Dyn*)get_section(shdr, sdata, elf_header.e_shnum, fd, string, ".dynamic",3);

/* get global offset table (.got section) */
got = get_section(shdr, sdata, elf_header.e_shnum, fd, string, ".got", 0);


shdr = (Elf32_Shdr*)sdata;
if (check_plt_infection(dynsym, got, dynstr)) infected |= A;
if (check_fake_entry(elf_header.e_entry)) infected |= B;
if (check_function_hijacking(elf_header.e_shnum, string, shdr)) infected |= C;
if (check_dynamic_infection(section_inf[3].size, dynamic)) infected |= D;
if (!infected) printf("\n [-] This file is clean!!\n\n");
else show_method();

close(fd);

return (0);
}

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

May 2012

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    37 Files
  • 2
    May 2nd
    53 Files
  • 3
    May 3rd
    33 Files
  • 4
    May 4th
    4 Files
  • 5
    May 5th
    10 Files
  • 6
    May 6th
    17 Files
  • 7
    May 7th
    19 Files
  • 8
    May 8th
    36 Files
  • 9
    May 9th
    34 Files
  • 10
    May 10th
    35 Files
  • 11
    May 11th
    20 Files
  • 12
    May 12th
    18 Files
  • 13
    May 13th
    11 Files
  • 14
    May 14th
    27 Files
  • 15
    May 15th
    58 Files
  • 16
    May 16th
    54 Files
  • 17
    May 17th
    25 Files
  • 18
    May 18th
    53 Files
  • 19
    May 19th
    9 Files
  • 20
    May 20th
    15 Files
  • 21
    May 21st
    25 Files
  • 22
    May 22nd
    32 Files
  • 23
    May 23rd
    35 Files
  • 24
    May 24th
    26 Files
  • 25
    May 25th
    25 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2012 Packet Storm. All rights reserved.

close