Easy Encrypt

Reverse Engineering · BearcatCTF 2025 · Sean

Problem

Description

Ghidra analysis

Main function

undefined8 main(void)

{
  long lVar1;
  undefined *puVar2;
  int iVar3;
  size_t sVar4;
  ulong uVar5;
  size_t *psVar6;
  long in_FS_OFFSET;
  size_t local_188;
  long local_180;
  undefined *local_178;
  undefined4 local_16c;
  undefined8 local_168;
  undefined8 local_160;
  undefined8 local_158;
  undefined local_150;
  char local_148 [264];
  long local_40;
  
  local_40 = *(long *)(in_FS_OFFSET + 0x28);
  puts("I dropped my flag somewhere! Can you find it for me?");
  fgets(local_148,0x100,stdin);
  sVar4 = strcspn(local_148,"\n");
  local_148[sVar4] = '\0';
  local_188 = strlen(local_148);
  local_168 = 0x7f04487763707073;
  local_160 = 0x435d4005406c0405;
  local_158 = 0x734107796803406e;
  local_150 = 0x4c;
  local_180 = local_188 - 1;
  uVar5 = ((local_188 + 0xf) / 0x10) * 0x10;
  for (psVar6 = &local_188; psVar6 != (size_t *)((long)&local_188 - (uVar5 & 0xfffffffffffff000));
      psVar6 = (size_t *)((long)psVar6 + -0x1000)) {
    *(undefined8 *)((long)psVar6 + -8) = *(undefined8 *)((long)psVar6 + -8);
  }
  lVar1 = -(ulong)((uint)uVar5 & 0xfff);
  if ((uVar5 & 0xfff) != 0) {
    *(undefined8 *)((long)psVar6 + ((ulong)((uint)uVar5 & 0xfff) - 8) + lVar1) =
         *(undefined8 *)((long)psVar6 + ((ulong)((uint)uVar5 & 0xfff) - 8) + lVar1);
  }
  sVar4 = local_188;
  local_178 = (undefined *)((long)psVar6 + lVar1);
  *(undefined8 *)((long)psVar6 + lVar1 + -8) = 0x10142f;
  memcpy((undefined *)((long)psVar6 + lVar1),local_148,sVar4);
  puVar2 = local_178;
  sVar4 = local_188;
  local_16c = 0x37333331;
  *(undefined8 *)((long)psVar6 + lVar1 + -8) = 0x101459;
  xor(puVar2,&local_16c,sVar4);
  puVar2 = local_178;
  *(undefined8 *)((long)psVar6 + lVar1 + -8) = 0x101477;
  iVar3 = memcmp(puVar2,&local_168,0x19);
  if (iVar3 == 0) {
    *(undefined8 *)((long)psVar6 + lVar1 + -8) = 0x10148a;
    puts("There it is!");
  }
  else {
    *(undefined8 *)((long)psVar6 + lVar1 + -8) = 0x10149b;
    puts("Hmmm... No that isn\'t right at all.");
  }
  if (local_40 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Solution

1. Encrypted Flag (local_168, local_160, local_158, local_150):

The program gives you the encrypted flag in hexadecimal form. The following values represent the encrypted flag:

local_168 = 0x7f04487763707073;
local_160 = 0x435d4005406c0405;
local_158 = 0x734107796803406e;
local_150 = 0x4c;

These values represent the flag in little-endian format (which means the least significant byte comes first). When you break them down into bytes:

  • 0x7f04487763707073 becomes:

    0x73, 0x70, 0x70, 0x63, 0x77, 0x48, 0x04, 0x7f
  • 0x7f04487763707073 becomes:

    0x05, 0x04, 0x6c, 0x40, 0x05, 0x40, 0x5d, 0x43

So on

2. XOR Key (local_16c):

The XOR key used for encryption is stored in local_16c. In the program, this is set to 0x37333331, which is "1337" in ASCII. Each character in "1337" corresponds to a byte:

  • 0x31 (ASCII '1')

  • 0x33 (ASCII '3')

  • 0x33 (ASCII '3')

  • 0x37 (ASCII '7')

3. XOR Decryption:

Given these values, you can now decrypt the flag using the XOR key "1337". The XOR operation reverses the encryption process. For each byte of the encrypted flag, you XOR it with the corresponding byte from the key (cycling through the key if necessary)

Flag: BCCTF{7H47_w4snt_s0_H4rD}

Last updated