1 min read

picoCTF - Reverse writeup (zh-TW)

picoCTF - Reverse writeup (zh-TW)

題目資訊

解題過程

Step 1: 偵察

直接執行觀察互動行為:

./ret

→ 要求輸入密碼,錯誤則顯示 Access denied

Step 2: 靜態掃描

使用 strings 掃描 .rodata,檢查是否硬編碼旗子或提示:

strings ret | grep -i pico

→ 顯示 Password correct, please see flag: picoCTF{Redacted}

直接取得 Flag: picoCTF{Redacted}

Step 3: 反編譯觀察(驗證程式邏輯)

undefined8 main(void)

{
  int iVar1;
  long in_FS_OFFSET;
  char local_68 [48];
  char local_38 [40];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  builtin_strncpy(local_38,"picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7",0x28);
  printf("Enter the password to unlock this file: ");
  __isoc99_scanf(&DAT_00102031,local_68);
  printf("You entered: %s\n",local_68);
  iVar1 = strcmp(local_68,local_38);
  if (iVar1 == 0) {
    puts("Password correct, please see flag: picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7d}");
    puts(local_38);
  }
  else {
    puts("Access denied");
  }
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return 0;
}

Ghidra 反編譯重點:

  • 程式把字串 "picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7"(注意少了最後的 d})以 builtin_strncpy(..., 0x28) 複製到 local_38
  • 接著 strcmp(local_68, local_38) 比對:
    • 輸入等於這段前綴字串,就印出成功訊息與完整 flag picoCTF{Redacted}
  • 因此「密碼」其實是前綴:picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7(輸入這串會觸發成功分支,然後程式自行印完整旗子)

學習重點

  • 入門 RE 題常把 flag/提示硬寫在 .rodata:先用 strings 快速偵察
  • 看清「比對點」與「成功分支」:本題以 strcmp 比對前綴,成功後才印出完整 flag