Compiled
First download the file from the room (https://tryhackme.com/room/compiled) in order to analyze it.
strings Compiled-1688545393558.Compiled
...
PTE1
u+UH
StringsIH
sForNoobH
Password:
DoYouEven%sCTF
__dso_handle
_init
Correct!
Try again!
...
Strings is for noob
Ghidra
undefined8 main(void)
{
int iVar1;
char local_28 [32];
fwrite("Password: ",1,10,stdout);
__isoc99_scanf("DoYouEven%sCTF",local_28);
iVar1 = strcmp(local_28,"__dso_handle");
if ((-1 < iVar1) && (iVar1 = strcmp(local_28,"__dso_handle"), iVar1 < 1)) {
printf("Try again!");
return 0;
}
iVar1 = strcmp(local_28,"_init");
if (iVar1 == 0) {
printf("Correct!");
}
else {
printf("Try again!");
}
return 0;
}
-
undefined8 main(void):main: This is the entry point of the program. Every C program starts execution here.void: Thevoidinside the parentheses means that themainfunction takes no arguments.undefined8: This indicates the return type.undefined8is often seen in decompiled code (like what you might get from Ghidra or IDA Pro). It essentially means "an 8-byte value of unspecified type". For our purposes, think of it as a generic return type, similar tointon many systems. The return value (0 in both success and failure cases) isn't crucial for solving the challenge.
-
int iVar1;:- Declares an integer variable named
iVar1. This variable will store the result of thestrcmpfunction calls.
- Declares an integer variable named
-
char local_28 [32];:- Declares a character array (a string) named
local_28. [32]: This array can hold up to 32 characters (including the null terminator,\0, which marks the end of a C string). This is where the user's input will be stored. The namelocal_28is typical of decompilers; it indicates a local variable at a specific offset on the stack.
- Declares a character array (a string) named
-
fwrite("Password: ",1,10,stdout);:- This line prints "Password: " to the console (standard output).
fwrite: A function that writes data to a stream."Password: ": The string to be written.1: The size (in bytes) of each element to be written (1 byte, because it's a character).10: The number of elements to write (10 characters in "Password: ").stdout: A predefined stream representing the standard output (usually the console).
-
__isoc99_scanf("DoYouEven%sCTF",local_28);:- This is the crucial line that reads user input. It's using the
scanffunction, a standard C input function. __isoc99_scanf: A specific version ofscanf(likely indicating the C standard used)."DoYouEven%sCTF": This is the format string. The%sis a format specifier. It tellsscanfto expect a string from the input. The input is expected to start with "DoYouEven", followed by the string we want to capture (%s), and it could continue with "CTF". However, the "CTF" part is not strictly enforced. The%swill read characters until it encounters whitespace (space, tab, newline).local_28: The address of thelocal_28array.scanfwill write the string it reads from the input into this array.
- This is the crucial line that reads user input. It's using the
-
iVar1 = strcmp(local_28,"__dso_handle");if ((-1 < iVar1) && (iVar1 = strcmp(local_28,"__dso_handle"), iVar1 < 1)) { ... }:strcmp(str1, str2): This function compares two strings lexicographically (like dictionary order).- Returns 0 if
str1andstr2are equal. - Returns a value less than 0 if
str1comes beforestr2alphabetically. - Returns a value greater than 0 if
str1comes afterstr2alphabetically.
- Returns 0 if
- The first
strcmpcompares the user input with "__dso_handle". - The
ifcondition is a bit convoluted. It checks ifiVar1is greater than -1 and ifiVar1(after being reassigned the result of the same comparison) is less than 1. - The result is that this
ifblock executes if and only ifiVar1is 0. In other words, this is a complicated way of checkingif (strcmp(local_28, "__dso_handle") == 0). If the strings are equal, it prints "Try again!" and exits. This is a red herring.
-
iVar1 = strcmp(local_28,"_init");if (iVar1 == 0) { ... } else { ... }:- This is the real password check.
strcmpis used again, this time comparing the user input with"_init".if (iVar1 == 0): If the result ofstrcmpis 0 (meaning the strings are equal), the "Correct!" message is printed.else: Otherwise, "Try again!" is printed.
-
return 0;:- This line exits the
mainfunction and returns a value of 0 to the operating system. A return value of 0 typically indicates successful execution.
- This line exits the
Solution
-
Input Format and
scanf's Behavior: Thescanfformat stringDoYouEven%sCTFis deceptive. While it suggests the input should beDoYouEven<PASSWORD>CTF, the%sspecifier reads characters only until it finds whitespace. The "CTF" part is a potential continuation, but not a requirement. Pressing Enter adds a newline character (\n), which is whitespace. -
Password: The code checks if the string captured by
%sis equal to"_init". -
Correct Input: Because of the newline added by pressing Enter, the correct input is:
DoYouEven_initscanfreadsDoYouEven.scanfencounters%sand starts reading intolocal_28.scanfreads_init.scanfencounters the newline (\n) from pressing Enter. Because newline is whitespace,scanfstops reading for%sat this point. The "CTF" part is ignored.local_28contains "_init".- The second
strcmpsucceeds.
Key Takeaways
scanfwith%sand Whitespace: This is the most important point.%sinscanfreads until any whitespace character is encountered (space, tab, newline, etc.). It does not require the rest of the format string to match exactly.- Trailing Newline: Pressing Enter adds a newline character (
\n) to the input. This acts as the whitespace that terminates the%sinput. - Format String as a Guide: The format string in
scanfprovides a guide for the expected input, but%swill stop reading at whitespace, regardless of the rest of the format string. - Red Herrings: The first
strcmpcheck and the "CTF" in the format string are distractions.