picoCTF "ret" Reverse Engineering Writeup
Challenge Info
- Platform: picoCTF
- Category: Reverse Engineering
- Challenge Link: https://play.picoctf.org/practice/challenge/372
Walkthrough
Step 1: Recon
Just run it and see how it behaves:
./ret
→ It prompts for a password, and shows Access denied if you get it wrong.
Step 2: Static Scan
Use strings to scan the .rodata section and check whether the flag or a hint is hardcoded:
strings ret | grep -i pico
→ It prints Password correct, please see flag: picoCTF{Redacted}
⇒ Flag obtained directly: picoCTF{Redacted}
Step 3: Decompile and Inspect (verifying the program logic)
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;
}Key points from the Ghidra decompilation:
- The program copies the string
"picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7"(note the missing trailingd}) intolocal_38viabuiltin_strncpy(..., 0x28) - It then compares with
strcmp(local_68, local_38):- If your input equals this prefix string, it prints the success message together with the complete flag
picoCTF{Redacted}
- If your input equals this prefix string, it prints the success message together with the complete flag
- So the "password" is really the prefix:
picoCTF{3lf_r3v3r5ing_succe55ful_7851ef7(entering this string triggers the success branch, and the program then prints the full flag on its own)
Takeaways
- Beginner RE challenges often hardcode the flag/hint straight into .rodata: reach for
stringsfirst for a quick recon pass - Identify the "comparison point" and the "success branch": here the
strcmponly checks a prefix, and the complete flag is only printed after a match
Member discussion