Checks
Checks is a rather simple program, it performs a few simple checks but took a while to fully understand as it is statically linked, preventing use of ltrace
to trace libc calls.
First Check
The first check the program performs is to retrieve the username of the user running the program.
And to then compare it with the string '800'.
To bypass this check, I opted to replace the username string with '800' inside gdb, however you could also just create another user account named '800'.
Second Check
The second check performed is to test if the value of the env var SECRET_REQ
is equal to coolenvvar
.
Getting past this check is simply setting the env var SECRET_REQ=coolenvvar
.
Third Check
This check uses the access(const char *path, int mode)
function to test if the file ./secrets.zip
is readable.
However the program never attempts to read this file so simply touch secrets.zip
is enough to complete this check.
Completion
Once all the checks have been passed, the program prints the flag. The flag is not computed from the results of the three checks and so all checks can actually just be skipped.
Interestingly, the program provided for this challenge was initially broken, the flag printing code was as follows:
Which constructs a string on the stack by writing two 8-byte values, then passing the address of the first byte of the string on the stack to printf. This is broken since the address of a value on the stack is dependent on the stack offset before the function is invoked, which is ultimately dependent on the base address the stack is mapped to which is either randomized between invokations if ASLR is enabled, or at the same system-dependent offset if ASLR is disabled.
Because of this it was not possible to solve the first given binary as the program would have to be run with the stack mapped to the same region as when the challenge developers ran the program to create the flag for the challenge.
At some point the binary was updated and the flag printing code was changed to:
Which first loads the string '88ED12AC' onto the stack and passes a pointer to it to strtoll with the base parameter being 0x10 = 16
which converts the string as a base16 representation into an integer.
The decoded integer is then printed back in hex representation by printf with the %X
format code.
So yes, most of this code is not necessary; in fact, the flag can be gained without even running the program with the second binary ¯_(ツ)_/¯.