Hi guys!!! Happy 2020 to you all. Hope you have a new year resolution to solve CTF ahahahah (just joking).
Today, we will be doing Hacker101 CTF “Hello World!”.
So based on the website, there is a input box ‘STDIN’ and a link to download a vulnerable binary program.
The first hint given for this CTF is “What does the application do?”.
I play around with the input box by inserting special characters, and random word. The web application will print out the exact word or special character being inserted into the input box.
What’s next? I went to download the binary program called ‘vulnerable’, I went to execute it but nothing happen. So I know that I have to debug the binary program.
But first I need to find out the details of the vulnerable binary program.
Here are some of the information that I have found:
# file vulnerable
vulnerable: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=ea1000564e33f4ad1901ebfe81bfc1fb3ea38fa2, not stripped
# readelf -h vulnerable
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4005b0
Start of program headers: 64 (bytes into file)
Start of section headers: 6808 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29
Based on the information given above, I find out that the program is in ELF executable file. ELF stands for Executable and Linkable Format also known as Extensible Linking Format. It is a common file format for executable files, object code, shared libraries and core dumps.
From here I went ahead to use ‘strings’ – to print out a sequence of printable characters in the program.
# strings vulnerable
/lib64/ld-linux-x86-64.so.2
libc.so.6
exit
puts
stdin
printf
fgetc
memset
getenv
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-X
AWAVA
AUATL
[]A\A]A^A_
FLAGS
What is your name?
Hello %s!
;*3$"
Based on the printable characters of the program, I can identify that ‘FLAGS’ where the flag will be print in the web application. Now we have to debug/reverse engineer the program called ‘vulnerable’.
I went to search up on reverse engineering on ELF executable file, it explain the reason why gdb tool is unable to read the symbols in the file and how to do basic reverse engineering for ELF 64-bit LSB executable file.
Moving on…
In the above code block, the command ‘readelf -h vulnerable’ gives us the entrypoint of the executable file. The entry-point is ‘0x4005b0’ which is the starting memory address for the executable file.
Time to debug the program…
I do ‘gdb vulnerable’ to gain a debugging session shell.
Do note that the file is 64-bit thus, once you disassemble main or x command it, you will see ‘rdp’, ‘rsp’ etc.
Afterwards, I do ‘x/200i 0x4005b0’
Basically, what I did was to display memory contents instruction of 200 elements at the address.
Hit the enter button a few times and discover that there is a function called ‘print_flags’.
The memory address to print out the flag in the web application is ‘0x4006ee’, the full address is ‘0x00000000004006ee’. Keep in the mind the memory address of ‘print_flags’.
Looking through the contents, I figured out that the fget() in the program accepts the stdin of the user which it will go to the main function where printf() will print out the input of the user.
Seeing fget() and printf(), I finally understood that I need to do a buffer overflow attack on the program to point the return address to the memory address of ‘print_flags’ to print out the flag.
Before exploiting the buffer, I need to find out the buffer of the program. So, I type in ‘disassemble main’ to find out the buffer.
‘$0x20’ is a hexdecimal value, converted to decimal the buffer is 32 bytes.
The stack = buffer[32] + rbp(8) + return address(8) = 48, why add 8 bytes for rbp and return address? Is because the program is 64-bit instead of 32-bit thus the memory address between each other is 8 bytes.
For the memory address of ‘print_flags’ to become the return address, I need to have the remaining 40 bytes to be overflow with ‘A’, in hex. is ‘\x41’.
In the web application, instead of inputting the characters and memory address in the form to submit, I input it in the URL bar using URL encoding format as if I use ascii character in the input box, I wouldn’t be able to input in the memory address of ‘print_flags’ as the hexdecimal value is a non-ascii character when it is converted.
In the URL bar is it should look like this:
/?stdin=%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%41%ee%06%40%00%00%00%00%00
I hit the enter button and I was able to get the flag. 
What I learned? To learn how to reverse engineer the program and analyse its content to be able to figured out that it is vulnerable to buffer overflow attack and the main objective is to have the return address point to the memory address of the function called ‘print_flags’ to output the flag in the web application.
That’s all folks 🙂
Author: Derek