Skip to content
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
ae5d3f0
prevent overrunning beyond the text segment in internal.c:original_ep
elfmaster Oct 3, 2018
b63a0d3
fixed bugs having to do with invalid symbol->st_name dereference
elfmaster Oct 4, 2018
84f399b
...
elfmaster Oct 9, 2018
1dd7b77
fixed elf_address_pointer and dw_read_location
elfmaster Oct 11, 2018
bf0053b
initial commit
Oct 12, 2018
dd30d14
implemented address to offset conversion helper functions
Oct 13, 2018
aa59757
implemented address to offset conversion helper functions
Oct 13, 2018
02db4ec
data segment injection implemented
Oct 13, 2018
8fd1a13
data segment injection implemented
Oct 13, 2018
2e0e6a8
data segment injection implemented
Oct 13, 2018
e428d3e
data segment injection implemented
Oct 13, 2018
21e30a1
data segment injection implemented
Oct 13, 2018
457060f
minor fixes
Oct 13, 2018
26b45bf
minor fixes
Oct 13, 2018
7b0eb3d
minor fixes
Oct 13, 2018
bcf6eed
minor fixes
Oct 13, 2018
2d3ec5a
implemented reverse_text_section infection
Dec 7, 2018
826ab11
minor fixes
Dec 7, 2018
2a1cc9a
minor fixes
Dec 7, 2018
23ac882
implemented interpending infection (appending at the end of code sect…
Dec 21, 2018
5f94ba7
implemented section offset re-alignment after infection
Dec 27, 2018
1de9f62
implemented section offset re-alignment after infection
Dec 27, 2018
4b5216a
implemented section offset re-alignment after infection
Dec 27, 2018
151a2f9
implemented section offset re-alignment after infection
Dec 27, 2018
c94acef
initial support for basic code injection
Jan 4, 2019
dfaf6cf
intiial code injection support (sync with master)
Jan 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
all:
gcc -O2 -g -fPIC -pie elfparse.c ../src/libelfmaster.a -o elfparse
gcc -O3 -g ldd.c ../src/libelfmaster.a -o ldd
gcc -O0 -g -fPIC -pie elfparse.c ../src/libelfmaster.a -o elfparse
gcc -O0 -g ldd.c ../src/libelfmaster.a -o ldd
gcc -O2 -g read_mem.c ../src/libelfmaster.a -o read_mem
gcc -O2 -g plt_dump.c ../src/libelfmaster.a -o plt_dump
gcc -O2 -g plt_dump2.c ../src/libelfmaster.a -o plt_dump2
Expand All @@ -18,5 +18,6 @@ all:
gcc ../utils/stripx.c -o stripx
./stripx test_stripped
./stripx test32_stripped
gcc -O2 -g code_injection.c ../src/libelfmaster.a -o code_injection
clean:
rm elfparse ldd plt_dump plt_dump2 sections eh_frame test test2 test32bit_pie test_pie test_stripped test32bit stripx symbols checksec test32_stripped
rm elfparse ldd plt_dump plt_dump2 sections eh_frame test test32bit_pie test_pie test_stripped test32bit stripx symbols checksec test32_stripped read_mem test2_pie code_injection
95 changes: 95 additions & 0 deletions examples/code_injection.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <elf.h>
#include <sys/types.h>
#include <search.h>
#include <sys/time.h>
#include <elf.h>
#include <link.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdbool.h>
#include <search.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <errno.h>
#include "../include/libelfmaster.h"
#include "../include/internal.h"

/*
* Opens a given file and checks if it contains an ELF magic. (More checks can be implemented).
*/
int main (int argc, char **argv)
{
elfobj_t obj1;
elfobj_t obj2;
elfobj_t objdest;
elf_error_t error;
uint64_t p_address;
uint64_t p_offset;
bool res;

// http://shell-storm.org/shellcode/files/shellcode-806.php
uint8_t stub[] = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48" \
"\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05";

if (argc != 3) {
printf("Usage: %s <host> <output binary>\n", argv[0]);
exit(EXIT_SUCCESS);
}
if (elf_open_object(argv[1], &obj1, ELF_LOAD_F_STRICT, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
/*
* In case the binary payload is residing in disk, we can use these functions to load
* it, as if it was an ELF file or some binary blob.
*
if (elf_has_header(argv[2], &res, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
if (res) {
if (elf_open_object(argv[2], &obj2, ELF_LOAD_F_STRICT, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
} else {
if (elf_open_stub(argv[2], &obj2, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
}
* Otherwise stubs can be also operated as byte-arrays.
*/

if (elf_init_stub(&obj2, stub, sizeof(stub), &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
if (elf_create_object(argv[2], &objdest, &obj1, obj1.size + obj2.size,
ELF_LOAD_F_STRICT, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
if (elf_inject_code(&objdest, &obj2, &p_offset, ELF_INJECT_F_POSTPEND, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
if(internal_offset_to_address(&objdest, p_offset, &p_address, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
printf("Payload written at offset: 0x%lx, address: 0x%lx\n", p_offset, p_address);

if (elf_commit_object(&objdest, objdest.size, 0, &error) == false) {
fprintf(stderr, "%s\n", elf_error_msg(&error));
return -1;
}
return 0;
}
8 changes: 8 additions & 0 deletions include/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,12 @@ bool phdr_sanity(elfobj_t *, void *);
* Get the address range of every function found in .eh_frame
*/
ssize_t dw_get_eh_frame_ranges(elfobj_t *);

uint64_t internal_address_to_rva(struct elfobj *, uint64_t);

uint64_t internal_segment_offset_delta(struct elfobj *, struct elf_segment *);

bool internal_offset_to_address(struct elfobj *, uint64_t, uint64_t *, elf_error_t *);

bool internal_address_to_offset(struct elfobj *, uint64_t, uint64_t *, elf_error_t *);
#endif // _LIBELFMASTER_INTERNAL_H_
46 changes: 46 additions & 0 deletions include/libelfmaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@

#define MAX_ERROR_STR_LEN 128

/*
* DT_PLTREL tag has two valid
* values, 0x7 and 0x11
*/
#define ELF_DT_PLTREL_RELA 0x7
#define ELF_DT_PLTREL_REL 0x11

/*
* In reality will never exceed 2,3, or 4 at the highest.
*/
Expand Down Expand Up @@ -72,6 +79,15 @@

#define SYMTAB_RECONSTRUCT_COUNT 8192

#define ELF_INJECT_F_PREPEND 0
#define ELF_INJECT_F_POSTPEND 1
#define ELF_INJECT_F_INTERPEND 2
#define ELF_ET_STUB -1
#define PAGE_SIZE 0x1000
#define PAGE_ALIGN(x) (x & ~(PAGE_SIZE - 1))
#define PAGE_ALIGN_UP(x) (PAGE_ALIGN(x) + PAGE_SIZE)


typedef struct elf_error {
char string[MAX_ERROR_STR_LEN];
int _errno;
Expand Down Expand Up @@ -192,6 +208,10 @@ struct pt_load {
uint32_t flag;
};

/*
* TODO
* Move the anomaly values to internal.h.
*/
/*
* Flags for anomalies on section headers
*/
Expand All @@ -202,6 +222,12 @@ struct pt_load {
#define INVALID_F_SHENTSIZE (1ULL << 4)
#define INVALID_F_SH_HEADERS (1ULL << 5)
#define INVALID_F_SHSTRTAB (1ULL << 6)

/*
* Flags for anomalies on dynamic segment
*/
#define INVALID_F_VITAL_DTAG_VALUE (1ULL << 7)

/*
* This struct is not meant to access directly. It is an opaque
* type. It is only accessed directly from within the API code
Expand All @@ -214,6 +240,7 @@ typedef struct elfobj {
unsigned int type;
unsigned long long int anomalies;
uint64_t load_flags;
int fd;
const char *path;
union {
Elf32_Ehdr *ehdr32;
Expand Down Expand Up @@ -295,6 +322,9 @@ typedef struct elfobj {
struct {
uint64_t size;
} relent;
struct {
uint64_t size;
} relaent;
struct {
uint64_t addr;
uint64_t size;
Expand Down Expand Up @@ -724,4 +754,20 @@ typedef enum typewidth {

bool elf_read_address(elfobj_t *, uint64_t, uint64_t *, typewidth_t);
bool elf_read_offset(elfobj_t *, uint64_t, uint64_t *, typewidth_t);


bool elf_has_header(const char *, bool *, elf_error_t *);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you get a chance put comments describing each function and its arguments. I need to do this too on some of mine. This is where we document our API for other developers who want to work on it.


bool elf_open_stub(const char *, struct elfobj *, elf_error_t *);

bool elf_init_stub(struct elfobj *, uint8_t *, size_t, elf_error_t *);

bool elf_create_object(const char *, struct elfobj *, struct elfobj *, size_t, uint64_t, elf_error_t *);

bool elf_commit_object(struct elfobj *, size_t, int, elf_error_t *);

bool elf_inject_code(struct elfobj *, struct elfobj *, uint64_t *, uint64_t, elf_error_t *);


#endif

Loading