Skip to content

Instantly share code, notes, and snippets.

@strazzere
Created July 14, 2017 21:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save strazzere/fe41a8af0e365437f6c40a4a2b56153c to your computer and use it in GitHub Desktop.
Save strazzere/fe41a8af0e365437f6c40a4a2b56153c to your computer and use it in GitHub Desktop.
Decryption for most Kony
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
char* _charxor(char* string, int length) {
// Often null bytes, sometimes not
char xor[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
char *output = malloc(length + 1);
long long low, high;
int i;
for( i = 0; i < length; i++) {
high = (((long)0x4EC4EC4F * string[i]) >> 0x20);
high = (high >> 2);
low = high + (high << 1);
high = high + (low << 2);
output[i] = (string[i] ^ xor[i & 0xF]) ^ (string[i] - high);
}
output[length] = 0x00;
return output;
}
char* charxor(char* string, int length) {
// Often null bytes, sometimes not
char xor[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
char *output = malloc(length + 1);
int i;
for( i = 0; i < length; i++) {
if(string[i] == 0x2e)
output[i] = (0x2d ^ xor[i & 0xF]) & 0xFF;
else
output[i] = (string[i] ^ xor[i & 0xF]) & 0xFF;
}
output[length] = 0x00;
return output;
}
int decrypt(FILE *ifp, FILE *ofp, unsigned char* key, unsigned char* iv) {
unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
// Get file size
fseek(ifp, 0L, SEEK_END);
int fsize = ftell(ifp);
// Seek back to beginning
fseek(ifp, 0L, SEEK_SET);
unsigned char *indata = malloc(fsize);
unsigned char *outdata = malloc(fsize);
int inlen, outlen;
// Read File
if((inlen = fread(indata, sizeof(char), fsize, ifp)) == fsize) {
// Fill in ckey and ivec
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
if(ctx == NULL) {
return -1;
}
// Same as EVP_CIPHER_CTX_reset() and EVP_CIPHER_CTX_init()
if(!EVP_CIPHER_CTX_cleanup(ctx)) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
if(!EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, NULL, NULL, 0)) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
if(!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 0 /* Zero for decrypt */)) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
if(!EVP_CipherUpdate(ctx, outdata, &outlen, indata, inlen)) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
int tmpLen;
if(!EVP_CipherFinal_ex(ctx, outdata, &tmpLen)) {
EVP_CIPHER_CTX_free(ctx);
return -1;
}
fwrite(outdata, 1, outlen, ofp);
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
free(indata);
free(outdata);
return 1;
}
free(indata);
free(outdata);
return 0;
}
int main(int argc, char *argv[]) {
if(argc != 5){
printf("Usage: <Timestamp> <AppId> <PackageName> /path/to/assets/js/startup.js\n");
return -1;
}
char *key_to_hash = malloc(0x100);
char *xorred = _charxor(argv[1], strlen(argv[1]));
strcat(key_to_hash, xorred);
free(xorred);
xorred = _charxor(argv[2], strlen(argv[2]));
strcat(key_to_hash, xorred);
free(xorred);
xorred = charxor(argv[3], strlen(argv[3]));
strcat(key_to_hash, xorred);
free(xorred);
printf(" [+] Build key to hash : ");
for(int i = 0; i < strlen(key_to_hash); i++) {
printf("%02x", key_to_hash[i] & 0xFF);
}
printf("\n");
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, key_to_hash, strlen(key_to_hash));
SHA256_Final(hash, &sha256);
printf(" [+] Hashed key for crypto : ");
for(int i = 0 ; i < SHA256_DIGEST_LENGTH; i++) {
printf("%02x", hash[i]);
}
printf("\n");
FILE *fIN, *fOUT;
//Decrypt file now
fIN = fopen(argv[4], "rb"); // File to be written; cipher text
if(fIN < 0) {
printf("Error - unable to open startup.js file : %s\n", argv[4]);
}
fOUT = fopen("decrypted.zip", "wb"); // File to be written; cipher text
if(fOUT < 0) {
printf("Error - unable to open file to write to\n");
}
// IV is often one or the other
unsigned char iv[] = "abcd1234efgh5678ijkl9012mnop6789";
// unsigned char iv[] = "00000000000000000000000000000000";
decrypt(fIN, fOUT, hash, iv);
fclose(fIN);
fclose(fOUT);
return 1;
}
all:
gcc decrypt.c -I/usr/local/opt/boringssl/include -L/usr/local/opt/boringssl/lib -lcrypto -o kony_decrypt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment