Skip to content

Instantly share code, notes, and snippets.

/ctf.c Secret

Created July 29, 2017 18:11
Show Gist options
  • Save anonymous/909e6af6a5d98985779887cbd1d1cbca to your computer and use it in GitHub Desktop.
Save anonymous/909e6af6a5d98985779887cbd1d1cbca to your computer and use it in GitHub Desktop.
hacked up reversed code
#include "stdbool.h"
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
struct key {
union {
uint32_t key_part[4];
uint8_t bytes[0x10];
};
};
struct key* gen_key(uint32_t in1, uint32_t in2, uint32_t in3)
{
struct key* res = malloc(sizeof(struct key));
for (uint32_t i = 0; i++ <= 0xff;)
{
uint32_t temp1 = in1 ^ (~in1 >> 0x10);
in1 = ((temp1 + i) * 0x1234567) ^ 0x89abcdef;
in2 ^= in1;
in3 += in1;
in1 = ((temp1 + i) * 0x89abcdef) ^ 0x1234567;
uint32_t old_in1 = in1;
in1 = in2;
in2 = in3;
in3 = old_in1;
}
res->key_part[0] = in1;
res->key_part[1] = in2;
res->key_part[2] = in3;
res->key_part[3] = in1 ^ in2 ^ in3;
return res;
}
void crypt_in_place(uint8_t* input, struct key* k, size_t input_len, uint8_t keystate_rotation)
{
uint8_t keystate[0x100];
// this has no effect, but is in the executable blob (obfuscated slightly).
// dunno.
memcpy(keystate, "strings4flag", 0xc);
for (uint32_t i = 0, next_keystate_val = keystate_rotation; i < sizeof(keystate); i++)
{
// yes, this seems to replace the possible flag string thing it seeds the keystate
// with... not sure why
keystate[i] = next_keystate_val++;
}
for (uint32_t i = 0, swap_temp = 0; i < sizeof(keystate); i++)
{
uint8_t keystate_byte = keystate[i];
uint8_t input_key_byte = k->bytes[i & 0xf];
swap_temp += keystate_byte + input_key_byte;
swap_temp &= 0xff;
keystate[i] = keystate[swap_temp];
keystate[swap_temp] = keystate_byte;
}
// early counter increment intentional -- just mimicry
for (uint32_t i = 0, swap_temp = 0; i++ < input_len;)
{
uint32_t keystate_index = i & 0xff;
uint8_t keystate_byte = keystate[keystate_index];
swap_temp += keystate_byte;
swap_temp &= 0xff;
uint8_t next_keystate_byte = keystate[swap_temp];
keystate[swap_temp] = keystate[keystate_index];
keystate[keystate_index] = next_keystate_byte;
input[i - 1] ^= keystate[0xff & (keystate[swap_temp] + next_keystate_byte)];
}
}
void attempt(struct key* k, uint8_t keystate_rotation, const uint8_t* in_data, size_t len)
{
bool printable = true;
uint8_t* working_data = malloc(len);
memcpy(working_data, in_data, len);
crypt_in_place(working_data, k, len, keystate_rotation);
printf("Keystate rotation %3d (%02x) ", keystate_rotation, keystate_rotation);
for (uint32_t i = 0; i < len; i++)
{
if (i && !(i&3)) printf(" ");
printf("%02x", working_data[i]);
printable = printable && isprint(working_data[i]);
}
if (printable)
printf("\n PRINTABLE: %.*s\n", (uint32_t) len, working_data);
else
printf("\n");
free(working_data);
}
int main(int argc, char* argv[])
{
struct key* k = gen_key(1095923727, 3459613537, 2312051101);
printf("key: %x %x %x %x\nrawkey: ", k->key_part[0], k->key_part[1], k->key_part[2], k->key_part[3]);
for (uint32_t i = 0; i < sizeof(k->bytes); i++)
printf("%02x", k->bytes[i]);
printf("\n\n");
// data to try decrypting goes here.
unsigned char data[] = "l\xd0\"\xc2\xdam\xc5Z\x92t\xca\xb9!w\x17u\'\xd6\x83\xfa\xd2\x05\xfbq\xd7\x93\x1fg\x17\n\x90\x08\x0f\x92";
// fuck it, brute force everything
for (uint32_t i = 0; i < 0x100; i++)
attempt(k, i, data, sizeof(data) - 1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment