vishwaCTF 2021: Suisse


Category: Reverse Engineering

498 points

Let’s Uno His Name and reduce 3 from each uno you found. Admin suffers from cardiovASCIIular disorders. So do obtain the flag accordingly.

Note: Do not include whitespaces in the flag if you find any, and your flag should be of the format vishwaCTF{flagtext}.

file: a.out


Given file is of course a binary.

file a.out
suisse: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.
so.2, BuildID[sha1]=d968f780f2d846afc4de470db594935c0b9c7870, for GNU/Linux 3.2.0, not stripped
Usage: ./a.out <argument>
./a.out blahblah
No FLAG for you lol

This time I used gdb.

gdb ./a.out 
GNU gdb (Debian 10.1-1.7)
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...
(No debugging symbols found in ./a.out)
(gdb) info function
All defined functions:

Non-debugging symbols:
0x0000000000001000  _init
0x00000000000010f0  [email protected]
0x0000000000001100  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()@plt
0x0000000000001110  [email protected]
0x0000000000001120  std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt
0x0000000000001130  std::allocator<char>::~allocator()@plt
0x0000000000001140  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator[](unsigned long) [email protected]
0x0000000000001150  [email protected]
0x0000000000001160  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)@plt
0x0000000000001170  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::length() [email protected]
0x0000000000001180  std::ios_base::Init::Init()@plt
0x0000000000001190  std::ostream::operator<<(int)@plt
0x00000000000011a0  [email protected]
0x00000000000011b0  std::allocator<char>::allocator()@plt
0x00000000000011c0  _start
0x00000000000011f0  deregister_tm_clones
0x0000000000001220  register_tm_clones
0x0000000000001260  __do_global_dtors_aux
0x00000000000012a0  frame_dummy
0x00000000000012a9  check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
0x00000000000013a8  _flag()
0x0000000000001530  main
0x000000000000163d  __static_initialization_and_destruction_0(int, int)
0x000000000000168a  _GLOBAL__sub_I__Z5checkRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
0x00000000000016b0  __libc_csu_init
0x0000000000001720  __libc_csu_fini
0x0000000000001728  _fini

Found interesting _flag() function. I decided to set up breakpoint at main and call the _flag().

(gdb) b main
Breakpoint 1 at 0x1538
(gdb) r
Starting program: /home/luc/Pobrane/a.out 

Breakpoint 1, 0x0000555555555538 in main ()
(gdb) print (void) _flag()
$1 = void
(gdb) c
111 88 107 81 113 93 52 118 56 104 102 88 85 104Usage: ./a.out <argument>
[Inferior 1 (process 139975) exited normally]

Ok, looks like a charcode. Let’s check it.

hexcode='111 88 107 81 113 93 52 118 56 104 102 88 85 104'
for i in hexcode.split(' '):
    print(chr(int(i)), end='')



Doesn’t looks like a flag. But there’s a hint in challenge description. Let’s try again with some change.

hexcode='111 88 107 81 113 93 52 118 56 104 102 88 85 104'
for i in hexcode.split(' '):
    print(chr(int(i) - 3), end='')



Looks better and combined with vishwaCTF{} makes flag whole.



Privacy Policy
luc © 2021