POSTS
MRMCDCTF2019: Sitting duck
Solution to Sitting duck (very easy) from MRMCDCTF 2019
Sitting duck was by far the easiest challenge I have written for the MRMCD 2019 CTF. It was targeted mostly at total CTF newbies that had absolutely no previous experience with reversing challenges.
The challenge gives you a binary file and the hint that it is solvable with very little experience.
When executing the file, it asks us for the flag. And if we don’t enter the correct flag, it tells us we are wrong.
user@host:$ ./sitting_duck
The password is the flag. What is the password?
foobar
Wrong. Try again.
user@host:$
What does this tell us? Well, now we know that the program has a quick way to check if the flag is correct. That must mean it has some information about the flag inside it, otherwise it could not tell a correct flag from a incorrect one. And the challenge here (and in most other reversing challenges) is to dig for this information and use it to infer the correct flag.
A common first step when dealing with a unknown binary file is using the file
command on it.
file
tries to identify the file type by checking for various magic values in the file.
You can learn more on its manpage (man file
).
user@host:$ file sitting_duck
sitting_duck: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c45e7154481418735d8207ac7a8133402ce4e013, for GNU/Linux 3.2.0, not stripped
Here it gives us the information that we are dealing with a 64 bit ELF file, the standard type for Linux executables on X86-64 systems. Nothing too spectacular.
A usual next step is to use strings
. strings
searches a file for all printable character sequences and puts them on the screen.
There are some adjustments you can make concerning what exactly to look for (see man strings
), but we stick with the defaults here:
user@host:$ strings sitting_duck
/lib64/ld-linux-x86-64.so.2
^qTH
mgUa
libc.so.6
puts
__stack_chk_fail
stdin
strtok
fgets
__cxa_finalize
strcmp
__libc_start_main
GLIBC_2.4
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
The password is the flag. What is the password?
##############################################
### Congratulations! This is the flag! ###
##############################################
Wrong. Try again.
;*3$"
MRMCDCTF{you_call_this_a_challenge_questionmark}
GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.7963
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
sitting_duck.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
puts@@GLIBC_2.2.5
stdin@@GLIBC_2.2.5
_edata
__stack_chk_fail@@GLIBC_2.4
password
__libc_start_main@@GLIBC_2.2.5
fgets@@GLIBC_2.2.5
__data_start
strcmp@@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
main
strtok@@GLIBC_2.2.5
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.gnu.build-id
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.data
.bss
.comment
What do we see here?
A lot of these strings were not part of the original source code, but put in by the compiler when creating the binary file. They describe sections of the binary (like ‘.text’), functions added by the compiler (like ‘deregister_tm_clones’) and functions imported from shared libraries (like ‘fgets@@GLIBC_2.2.5’). We can even see the exact compiler version that was used to build the program: ‘GCC: (Ubuntu 8.3.0-6ubuntu1) 8.3.0’. Information like this can be found in most Linux executables, but none of it is especially interesting here.
Other strings obviously come from the programmer: We see the “What is the password?”-message, the “Wrong. Try again.”-message and even the “Congratulations!- message that will be displayed once the correct flag is entered.
And there is one even more interesting string in the binary: ‘MRMCDCTF{you_call_this_a_challenge_questionmark}‘.
Well, here is is: The flag is contained in the binary in clear text.
A quick check confirms it:
user@host:$ ./sitting_duck
The password is the flag. What is the password?
MRMCDCTF{you_call_this_a_challenge_questionmark}
##############################################
### Congratulations! This is the flag! ###
##############################################
And so ‘MRMCDCTF{you_call_this_a_challenge_questionmark}’ really is the solution. Not so hard, was it?
Fun fact: There was another challenge (‘Hacker Protocols’) that was designed as a sort of sanity check (a challenge that gives you really few point basically for free). That challenge was to log onto IRC and join the CTFs official channel. The flag was displayed openly in the channel topic. That challenge was solved fewer times than sitting duck.