👾
Elijah's CTF Blog
  • 👋Home
  • 🇲🇾Wargames.MY CTF 2024
    • Credentials (crypto)
    • Stones (rev)
    • Rick'S Algorithm (crypto)
    • Rick'S Algorithm 2 (crypto)
    • Hohoho 3 continue (crypto)
  • 🎄Advent of CTF 2024
    • Jingle Bell ROP (pwn)
    • help (pwn)
  • Backdoor CTF 24
    • [rev] Ratatouille
  • 🇭🇰HKCERT CTF 24
    • Shellcode Runner 3 + Revenge (pwn)
    • ISH (1) (pwn)
    • Cyp.ress (rev)
    • Void (rev)
  • 🇮🇹ECSC 2024
    • ➕OffTopic (crypto)
  • 🎩Greyhats WelcomeCTF 24
    • EE2026 (misc)
  • 🚆UIUCTF 24
    • Syscalls (pwn)
    • Summarize (rev)
    • X Marked the Spot (crypto)
    • Without a Trace (crypto)
    • Determined (crypto)
    • Naptime (crypto)
    • Snore Signatures (crypto)
  • 🪼Jelly CTF 24
    • Cherry (crypto)
    • the_brewing_secrets (crypto)
  • 👨‍🦯vsCTF 24
    • Dream (crypto)
    • Cosmic Ray V3 (pwn)
  • 😎AKASEC CTF 24
    • Warmup (pwn)
    • Good_trip (pwn)
    • Sperm Rev (rev)
    • Paranoia (rev)
    • Grip (rev)
    • Risks (rev)
    • Lost (crypto)
  • 😁L3AK CTF 24
    • oorrww (pwn)
    • angry (rev)
    • Related (crypto)
    • BatBot (web-misc)
    • Matrix Magic (crypto)
  • 🥹CDDC Qualifiers 2024
    • WASM (rev)
    • crashMe (pwn)
Powered by GitBook
On this page
  1. AKASEC CTF 24

Grip (rev)

its...its...Grippy

Last updated 11 months ago

This binary has an initialisation routine which involves printing :3 followed by calling exit(). We can bypass the exit() call and allow the program to continue running by patching the call to exit() with some other instruction such as a jmp. This allows the program to continue executing the main function.

The decompiled main code looks as follows:

undefined8 main(void)

{
  undefined8 *puVar1;
  long in_FS_OFFSET;
  ulong local_d0;
  undefined8 local_b8;
  undefined8 local_b0;
  undefined8 local_a8;
  undefined8 local_a0;
  undefined8 local_98;
  undefined8 local_90;
  undefined8 local_88;
  undefined8 local_80;
  undefined8 local_78;
  undefined8 local_70;
  undefined8 local_68;
  undefined8 local_60;
  undefined8 local_58;
  undefined8 local_50;
  undefined8 local_48;
  undefined5 local_40;
  undefined3 uStack_3b;
  undefined5 uStack_38;
  undefined8 local_33;
  long local_20;
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  local_b8 = 0xb21e71ba177bbaa7;
  local_b0 = 0xf2f2dad7f679ba96;
  local_a8 = 0xba32c30ab77bbaf2;
  local_a0 = 0xcbd3d5c3d1dbd14a;
  local_98 = 0xc9c4c481d848bac3;
  local_90 = 0xba22b77bba84c0ef;
  local_88 = 0xc0efc94aba2aa77b;
  local_80 = 0xef48bad483dbd384;
  local_78 = 0xbacdc9c284de81d2;
  local_70 = 0x3516a77bba2eb77b;
  local_68 = 0xea19f2f2f2f23eb7;
  local_60 = 0x22f7b644fd3eb779;
  local_58 = 0x3eb779307bb00271;
  local_50 = 0xf33eb77122f7a67a;
  local_48 = 0xba621084e93e8f71;
  local_40 = 0xba960ab779;
  uStack_3b = 0xd7f6d9;
  uStack_38 = 0x86f2f2f2da;
  local_33 = 0x313bf2f2f2f21af7;
  for (local_d0 = 0; local_d0 < 0x8d; local_d0 = local_d0 + 1) {
    *(byte *)((long)&local_b8 + local_d0) = *(byte *)((long)&local_b8 + local_d0) ^ 0xf2;
  }
  puVar1 = (undefined8 *)mmap((void *)0x0,0x8d,6,0x22,-1,0);
  *puVar1 = local_b8;
  puVar1[1] = local_b0;
  puVar1[2] = local_a8;
  puVar1[3] = local_a0;
  puVar1[4] = local_98;
  puVar1[5] = local_90;
  puVar1[6] = local_88;
  puVar1[7] = local_80;
  puVar1[8] = local_78;
  puVar1[9] = local_70;
  puVar1[10] = local_68;
  puVar1[0xb] = local_60;
  puVar1[0xc] = local_58;
  puVar1[0xd] = local_50;
  puVar1[0xe] = local_48;
  puVar1[0xf] = CONCAT35(uStack_3b,local_40);
  *(ulong *)((long)puVar1 + 0x7d) = CONCAT53(uStack_38,uStack_3b);
  *(undefined8 *)((long)puVar1 + 0x85) = local_33;
  (*(code *)puVar1)();
  puts(":3");
  if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Essentially, the local variables represent the bytecode to be executed. The bytecode first undergoes an XOR decryption operation, then the bytecode is loaded into the memory at the address puVar1 and executed.

I then set a breakpoint at the line where the bytecode is executed to see what the bytecode does. The bytecode basically writes characters into the stack then slowly decrypts them, giving us the flag: akasec{sh1tty_p4ck3d_b1n4ry}

😎
14KB
grippy
Grippy binary file
Unpatched binary code
Patched binary file