on our regular checkups of our secret flag storage server we found out that we were hit by ransomware!
the original flag data is nowhere to be found, but luckily we not only have the encrypted file but also the encryption program itself.
decompile the executable with hex-rays and go to the main function:
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v3; // al
char v5; // [rsp+7h] [rbp-39h]
unsigned int seed[2]; // [rsp+8h] [rbp-38h] BYREF
signed __int64 i; // [rsp+10h] [rbp-30h]
FILE *stream; // [rsp+18h] [rbp-28h]
size_t size; // [rsp+20h] [rbp-20h]
void *ptr; // [rsp+28h] [rbp-18h]
FILE *s; // [rsp+30h] [rbp-10h]
unsigned __int64 v12; // [rsp+38h] [rbp-8h]
v12 = __readfsqword(0x28u);
stream = fopen("flag", "rb");
fseek(stream, 0, 2);
size = ftell(stream);
fseek(stream, 0, 0);
ptr = malloc(size);
fread(ptr, size, 1u, stream);
fclose(stream);
seed[0] = time(nullptr);
srand(seed[0]);
for ( i = 0; i < (__int64)size; ++i )
{
*((_BYTE *)ptr + i) ^= rand();
v3 = rand();
v5 = *((_BYTE *)ptr + i);
seed[1] = v3 & 7;
*((_BYTE *)ptr + i) = __ROL1__(v5, v3 & 7);
}
s = fopen("flag.enc", "wb");
fwrite(seed, 1u, 4u, s);
fwrite(ptr, 1u, size, s);
fclose(s);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
static inline uint8_t rol8(uint8_t val, int shift) {
shift &= 7;
if (shift == 0) return val;
return (uint8_t) ((val << shift) | (val >> (8 - shift)));
}
int main(void) {
FILE *stream = fopen("flag", "rb");
fseek(stream, 0, SEEK_END);
long size = ftell(stream);
fseek(stream, 0, SEEK_SET);
uint8_t *data = malloc(size);
fread(data, size, 1, stream);
fclose(stream);
uint32_t seed = (uint32_t) time(NULL);
srand(seed);
for (long i = 0; i < size; i++) {
data[i] ^= (uint8_t) rand();
int shift = rand() & 7;
data[i] = rol8(data[i], shift);
}
FILE *out = fopen("flag.enc", "wb");
fwrite(&seed, 1, 4, out);
fwrite(data, 1, size, out);
fclose(out);
free(data);
return 0;
}
reversing the logic
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
static inline uint8_t ror8(uint8_t val, int shift) {
shift &= 7;
if (shift == 0) return val;
return (uint8_t) ((val >> shift) | (val << (8 - shift)));
}
int main(void) {
FILE *stream = fopen("flag.enc", "rb");
uint32_t seed;
fread(&seed, 1, 4, stream);
long pos = ftell(stream);
fseek(stream, 0, SEEK_END);
long size = ftell(stream) - pos;
fseek(stream, pos, SEEK_SET);
uint8_t *data = malloc(size);
fread(data, size, 1, stream);
fclose(stream);
srand(seed);
for (long i = 0; i < size; i++) {
uint8_t key = rand();
uint8_t shift = rand() & 7;
data[i] = ror8(data[i], shift);
data[i] ^= key;
}
FILE *out = fopen("flag.dec", "wb");
fwrite(data, 1, size, out);
fclose(out);
free(data);
return 0;
}