akira-bruteforce/public-key-patch/read-trailer.c
2025-03-13 12:31:49 +07:00

335 lines
11 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <nettle/yarrow.h>
#include <assert.h>
#include <stdint.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
const char *PRIVATE_KEY_PEM =
"-----BEGIN PRIVATE KEY-----\n"
"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\n"
"sOKmXagzbDe1FDdgyr5b/0WEv0xq\n"
"-----END PRIVATE KEY-----\n";
uint32_t swap32(uint32_t a1)
{
return (a1 >> 8 << 16) & 0xFF0000 | (a1 << 8 >> 16) & 0xFF00 | (a1 >> 24) | (a1 << 24);
}
void inverse_swap32_buffer(uint32_t *buffer, size_t size)
{
for (size_t i = 0; i < size / 4; i++)
{
buffer[i] = swap32(buffer[i]); // Applying swap32 again to reverse
}
}
void hexdump(const char *title, uint8_t *data, int len)
{
printf("%s: ", title);
for (int i = 0; i < len; i++)
{
printf("%02x", data[i]);
if ((i + 1) % 16 == 0)
{
printf("\n");
}
}
printf("\n");
}
void hexprint(uint8_t *data, int len)
{
for (int i = 0; i < len; i++)
{
printf("%02x", data[i]);
}
printf(" ");
}
void split_back(uint64_t a1, // original byte length of first array
uint64_t a3, // original byte length of second array
const uint32_t *merged, // merged (and swapped) array
uint32_t *out1, // output: first array (unswapped)
uint32_t *out2) // output: second array (unswapped)
{
// Compute word counts for each array.
size_t count1 = a1 >> 2;
size_t count2 = a3 >> 2;
size_t total = count1 + count2;
// Determine interleaving pattern (must match merge_and_swap):
// If a1 is 32 bytes (i.e. 8 words) then every 3rd word starting at index 2 came from the second array.
// Otherwise, every 2nd word starting at index 1 came from the second array.
int next_arr2_index, arr2_step;
if (a1 == 32)
{
next_arr2_index = 2;
arr2_step = 3;
}
else
{
next_arr2_index = 1;
arr2_step = 2;
}
size_t index1 = 0, index2 = 0;
for (size_t i = 0; i < total; i++)
{
// If this position originally came from arr2, recover it there.
if ((int)i == next_arr2_index)
{
out2[index2++] = swap32(merged[i]);
next_arr2_index += arr2_step;
}
else
{
// Otherwise, it came from arr1.
out1[index1++] = swap32(merged[i]);
}
}
}
void gen_key(uint64_t t, char *dest)
{
struct yarrow256_ctx ctx;
yarrow256_init(&ctx, 0, NULL);
char seed[32];
snprintf(seed, sizeof(seed), "%lld", t);
yarrow256_seed(&ctx, strlen(seed), seed);
char buffer[32];
yarrow256_random(&ctx, 32, buffer);
for (int i =0; i < sizeof(buffer); i++) {
printf("%02x", (unsigned char )(buffer[i]));
}
memcpy(dest, buffer, 32);
printf("\n");
}
static uint64_t *timestamps;
static char **timestamp_random;
static int timestamp_count;
int readlog(char *logfile)
{
//read log file
FILE *fp = fopen(logfile, "rb");
if (fp == NULL) {
printf("Error: Unable to open file %s\n", logfile);
return 1;
}
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buffer = malloc(fsize + 1);
if (buffer == NULL) {
printf("Error: Unable to allocate memory\n");
return 1;
}
fread(buffer, fsize, 1, fp);
fclose(fp);
uint64_t *t = (uint64_t *)buffer;
for (int i = 0; i < fsize/sizeof(uint64_t); i++) {
if (t[i] < 1700000000000000000) {
break;
}
if (t[i] > 1800000000000000000) {
break;
}
printf("t = %lld: ", t[i]);
char *random = (char *)malloc(32);
gen_key(t[i], random);
timestamp_random = (char **)realloc(timestamp_random, (i+1)*sizeof(char *));
timestamp_random[i] = random;
timestamp_count = i + 1;
}
timestamps = t;
return 0;
}
uint64_t search_timestamp(char *data, int len)
{
for (int i = 0; i < timestamp_count; i++) {
if (memcmp(timestamp_random[i], data, len)==0) {
return timestamps[i];
}
}
return 0;
}
int main(int argc, char *argv[])
{
if (argc > 1)
{
if (argc > 2) {
readlog(argv[2]);
}
const char *input_filename = argv[1];
FILE *input_file = fopen(input_filename, "rb");
if (!input_file)
{
perror("Error opening input file");
return EXIT_FAILURE;
}
fseek(input_file, 0, SEEK_END);
long file_size = ftell(input_file);
if (file_size < 512)
{
printf("File is smaller than 512 bytes, processing entire file.\n");
file_size = 512;
}
fseek(input_file, file_size - 512, SEEK_SET);
uint8_t buffer[512];
size_t bytes_read = fread(buffer, 1, 512, input_file);
fclose(input_file);
if (bytes_read == 0)
{
perror("Error reading file");
return EXIT_FAILURE;
}
int inlen = 512;
inverse_swap32_buffer((uint32_t *)buffer, bytes_read);
BIO *bio = BIO_new_mem_buf(PRIVATE_KEY_PEM, -1);
if (!bio)
{
perror("Error creating BIO");
return EXIT_FAILURE;
}
RSA *rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
BIO_free(bio);
if (!rsa)
{
printf("Error reading private key\n");
return EXIT_FAILURE;
}
unsigned char *encrypted = buffer;
unsigned char *decrypted = malloc(RSA_size(rsa));
if (!decrypted)
{
printf("Error allocating memory\n");
return EXIT_FAILURE;
}
int decrypted_len = RSA_private_decrypt(inlen, encrypted, decrypted, rsa, RSA_PKCS1_PADDING);
if (decrypted_len == -1)
{
printf("Error decrypting\n");
return EXIT_FAILURE;
}
RSA_free(rsa);
uint8_t chacha20_key[32];
uint8_t chacha20_nonce[16];
uint8_t *start_chacha = (uint8_t *)decrypted + 11;
split_back(32, 16, (uint32_t *)start_chacha, (uint32_t *)chacha20_key, (uint32_t *)chacha20_nonce);
hexdump("chacha20_key", chacha20_key, 32);
uint64_t t1 = search_timestamp(chacha20_key, 32);
if (t1 != 0) {
printf("T1 = %lld\n\n", t1);
}
hexdump("chacha20_nonce", chacha20_nonce, 16);
uint64_t t2 = search_timestamp(chacha20_nonce, 16);
if (t2 != 0) {
printf("T2 = %lld\n\n", t2);
}
uint8_t *start_kcipher2 = (uint8_t *)decrypted + 59;
uint8_t kcipher2_key[16];
uint8_t kcipher2_iv[16];
split_back(16, 16, (uint32_t *)start_kcipher2, (uint32_t *)kcipher2_key, (uint32_t *)kcipher2_iv);
hexdump("kcipher2_key", kcipher2_key, 16);
uint64_t t3 = search_timestamp(kcipher2_key, 16);
if (t3 != 0) {
printf("T3 = %lld\n\n", t3);
}
hexdump("kcipher2_iv", kcipher2_iv, 16);
uint64_t t4 = search_timestamp(kcipher2_iv, 16);
if (t4 != 0) {
printf("T4 = %lld\n", t4);
}
if (timestamp_count > 0) {
printf("\n");
printf("T4 - T3 = %d\n", t4 - t3);
printf("T3 - T1 = %d\n", t3 - t1);
printf("T2 - T1 = %d\n", t2 - t1);
}
}
else
{
printf("No arguments provided\n");
}
}