aes-finder icon indicating copy to clipboard operation
aes-finder copied to clipboard

Need some help

Open halloweeks opened this issue 9 months ago • 2 comments

I am writing my own aes keys finding code in c language for jni android project, key finding works fine but problem is 'little endian', my code able to find only big endian keys

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdbool.h>

#include "table.h" // aes table

#ifndef process_vm_readv
    #include <sys/syscall.h>
    #include <asm/unistd.h>
    
    ssize_t process_vm_readv(pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags) {
        return syscall(__NR_process_vm_readv, pid, local_iov, liovcnt, remote_iov, riovcnt, flags);
    }
#endif


ssize_t read_process_memory(pid_t pid, uintptr_t address, void *value, size_t size) {
    struct iovec local[1];
    struct iovec remote[1];
    local[0].iov_base = value;
    local[0].iov_len = size;
    remote[0].iov_base = (void*)address;
    remote[0].iov_len = size;
    return process_vm_readv(pid, local, 1, remote, 1, 0);
}

pid_t find_pid(const char *process_name) {
    DIR *dir = opendir("/proc");
    struct dirent *entry = NULL;
    char cmdline_path[256];
    char cmdline[256];
    int fd;
    
    if (dir == NULL) {
        return -1;
    }
    
    while ((entry = readdir(dir)) != NULL) {
        if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0) || (entry->d_type != DT_DIR) || (strspn(entry->d_name, "0123456789") != strlen(entry->d_name))) {
            continue;
        }
        snprintf(cmdline_path, sizeof(cmdline_path), "/proc/%s/cmdline", entry->d_name);
        fd = open(cmdline_path, O_RDONLY);
        read(fd, cmdline, 256);
        close(fd);
        
        if (strstr(cmdline, process_name) != NULL) {
            closedir(dir);
            return atoi(entry->d_name);
        }
    }
    closedir(dir);
    return -1;
}

uint8_t get_module_address(pid_t process_id, const char *module_name, uint64_t *start_addr, uint64_t *end_addr) {
    char filename[256];
    char line[1024];
    FILE *fp = NULL;
    uint8_t address_found = 0;
    uint64_t start, end;
    uint8_t permission;
    
    snprintf(filename, sizeof(filename), "/proc/%d/maps", process_id);
    
    if (!(fp = fopen(filename, "r"))) {
        return 0;
    }
    
    while (fgets(line, sizeof(line), fp)) {
        if (strstr(line, module_name)) {
            if (sscanf(line, "%lx-%lx %c", &start, &end, &permission) == 3) {
                if (permission != 'r') {
                    continue;
                }
                address_found = 1;
                *start_addr = start;
                *end_addr = end;
                break;
            }
        }
    }
    
    fclose(fp);
    return address_found;
}

// Detection aes 128 encryption key
bool aes128_detect_enc(const unsigned int *data) {
	unsigned int roundkey[44];
	
	roundkey[0] = data[0];
	roundkey[1] = data[1];
	roundkey[2] = data[2];
	roundkey[3] = data[3];
	
	for (unsigned char index = 4; index < 44; index += 4) {
		roundkey[index] = roundkey[index - 4] ^ 
			(Te4[(roundkey[index - 1] >> 16) & 0xff] & 0xff000000) ^ 
			(Te4[(roundkey[index - 1] >>  8) & 0xff] & 0x00ff0000) ^ 
			(Te4[(roundkey[index - 1] >>  0) & 0xff] & 0x0000ff00) ^ 
			(Te4[(roundkey[index - 1] >> 24) & 0xff] & 0x000000ff) ^ rcon[index / 4 - 1];
		roundkey[index + 1] = roundkey[index - 3] ^ roundkey[index];
		roundkey[index + 2] = roundkey[index - 2] ^ roundkey[index + 1];
		roundkey[index + 3] = roundkey[index - 1] ^ roundkey[index + 2];
	}
	
	for (int index = 0; index < 44; index++) {
		if (roundkey[index] != data[index]) {
			return false;
		}
	}
	
	return true;
}

bool aes128_detect_dec(const unsigned int *data) {
	unsigned int roundkey[44];
	
	roundkey[0] = data[40];
    roundkey[1] = data[41];
    roundkey[2] = data[42];
    roundkey[3] = data[43];
    
    
    for (unsigned char index = 4; index < 44; index += 4) {
		roundkey[index] = roundkey[index - 4] ^ 
			(Te4[(roundkey[index - 1] >> 16) & 0xff] & 0xff000000) ^ 
			(Te4[(roundkey[index - 1] >>  8) & 0xff] & 0x00ff0000) ^ 
			(Te4[(roundkey[index - 1] >>  0) & 0xff] & 0x0000ff00) ^ 
			(Te4[(roundkey[index - 1] >> 24) & 0xff] & 0x000000ff) ^ rcon[index / 4 - 1];
		roundkey[index + 1] = roundkey[index - 3] ^ roundkey[index];
		roundkey[index + 2] = roundkey[index - 2] ^ roundkey[index + 1];
		roundkey[index + 3] = roundkey[index - 1] ^ roundkey[index + 2];
	}
	
	unsigned int temp;
	
	// Next, invert the order of the round keys.
	for (unsigned char i = 0, j = 40; i < j; i += 4, j -= 4) {
		for (uint8_t k = 0; k < 4; k++) {
			temp = roundkey[i + k];
			roundkey[i + k] = roundkey[j + k];
			roundkey[j + k] = temp;
		}
	}
	
    // Finally, apply the inverse MixColumn transform to all round keys except the first and last.
    for (unsigned char index = 4; index < 40; index += 4) {
        roundkey[index] =
            Td0[Te4[(roundkey[index] >> 24) & 0xff] & 0xff] ^
            Td1[Te4[(roundkey[index] >> 16) & 0xff] & 0xff] ^
            Td2[Te4[(roundkey[index] >>  8) & 0xff] & 0xff] ^
            Td3[Te4[(roundkey[index] >>  0) & 0xff] & 0xff];
        roundkey[index + 1] =
            Td0[Te4[(roundkey[index + 1] >> 24) & 0xff] & 0xff] ^
            Td1[Te4[(roundkey[index + 1] >> 16) & 0xff] & 0xff] ^
            Td2[Te4[(roundkey[index + 1] >>  8) & 0xff] & 0xff] ^
            Td3[Te4[(roundkey[index + 1] >>  0) & 0xff] & 0xff];
        roundkey[index + 2] =
            Td0[Te4[(roundkey[index + 2] >> 24) & 0xff] & 0xff] ^
            Td1[Te4[(roundkey[index + 2] >> 16) & 0xff] & 0xff] ^
            Td2[Te4[(roundkey[index + 2] >>  8) & 0xff] & 0xff] ^
            Td3[Te4[(roundkey[index + 2] >>  0) & 0xff] & 0xff];
        roundkey[index + 3] =
            Td0[Te4[(roundkey[index + 3] >> 24) & 0xff] & 0xff] ^
            Td1[Te4[(roundkey[index + 3] >> 16) & 0xff] & 0xff] ^
            Td2[Te4[(roundkey[index + 3] >>  8) & 0xff] & 0xff] ^
            Td3[Te4[(roundkey[index + 3] >>  0) & 0xff] & 0xff];
    }
    
    for (int x = 0; x < 44; x++) {
		if (roundkey[x] != data[x]) {
			return false;
		}
	}
	
	return true;
}

void find_keys(const unsigned long long address, const uint8_t *buffer) {
	uint32_t *data = (uint32_t*)buffer;
	
	if (aes128_detect_enc(data)) {
		printf("[%p] Found AES-128 encryption key: 0x", (void*)address);
		for (int index = 0; index < 4; index++) {
			printf("%X", data[index]);
		}
		printf("\n");
	} else if (aes128_detect_dec(data)) {
		printf("[%p] Found AES-128 decryption key: 0x", (void*)address);
		for (int index = 40; index < 44; index++) {
			printf("%X", data[index]);
		}
		printf("\n");
	}
}

int main(int argc, const char *argv[]) {
	const char* package = argv[1]; // target program or application
	const char* module = "[stack]"; // target module
	
	uint64_t start = 0, end = 0;
	uint8_t data[240];
    
	pid_t pid = -1;
	
	printf("[INFO] Waiting for opening '%s' process\n", package);
	
	while (pid == -1) {
		pid = find_pid(package);
	}
	
	printf("[INFO] Process '%s' is now open pid %d\n", package, pid);
	
	printf("[INFO] Searching keys...\n");
	
	if (!get_module_address(pid, module, &start, &end)) {
		printf("[ERROR] Can't find module address\n");
		return 1;
	}
	
	uint64_t address = start;
	uint64_t remaining = end - start;
	
	while (remaining > 0) {
		if (read_process_memory(pid, address, data, 240) == -1) {
			printf("[ERROR] Can't read memory at %p\n", (void*)&start);
			break;
		}
		
		find_keys(address, data);
		
		remaining--;
		address++;
	}
	
	return 0;
}

halloweeks avatar May 14 '24 06:05 halloweeks