Lab 13 - CTF
Task: Hidden in Plain Sight
The hidden-in-plain-sight-1/support/link
binary provides everything you need.
Find a way to use it.
TIP: If you want a main function to be done right, you gotta do it yourself.
If you are having trouble solving this exercise, check this.
Task: Hidden in Plain Sight 2
Analyze the hidden-in-plain-sight-2/support/link2
binary.
Executing it is no longer a mystery, but it will be a bit more challenging to reach the flag.
TIP: Not all functions are private.
In case you get stuck, feel free to take a look at this!
Task: Look at Him Go
The look-at-him-go/support/dynamic
binary is executable this time and its sole purpose is to obtain the flag and place it somewhere in memory.
No tricks here.
TIP: GDB is your friend.
If you're unable to progress in this exercise, reference the GDB lab and this.
Task: Playing God
The playing-god/support/dynamic2
binary asks you to guess a number between 1 and 100000.
Find a better way to discover it.
To help you solve this exercise, like in the previous one, make sure to keep an eye on the registers!
Task: Indirect Business
The indirect-business/support/buff-ovf
binary contains a classic vulnerability.
Use the input to alter the data in your favor.
If you experience a neural buffer overflow, take a look at the relevant lab and at online examples.
If that still doesn't work, keep in mind that the great cybersecurity expert named Sun Tzu was a big proponent of bruteforce attacks.
Task: RIP My Buffers Off
The rip-my-buffers-off/support/buff-ovf2
binary does not use the get_flag()
function, but it offers an opportunity to call it.
TIP: Where can a function address be overwritten?
This example, albeit also linked in the previous exercise, is still a great resource to help you solve this exercise.
Task: Feeling Chained
Follow the sequence of operations in the functions of the binary at feeling-chained/support/buff-ovf3
.
Identify the necessary ones and... you already know how to call them.
If you cannot find your way through this exercise, look for variables that you need to overwrite with specific values in order to finish the exploit, and think of their positioning on the stack. The previously mentioned online example is still highly relevant.
Task: ROP
rop/support/rop
is a 64-bit binary with a simple buffer overflow.
However, it has NX enabled, so normal shellcode will not work.
Find a way to create a working exploit.
TIP: On x86_64, function arguments are no longer found on the stack but in registers.
If you're having trouble with this exercise, you may use this.
Keep in mind that peda
's functionality may be a bit different from that of the provided setup, but you should have this.
In pwndbg
, you can use something like rop --grep "pop rsi"
.
CTF
In this laboratory, you will have to apply most of the concepts presented throughout this course under the format of Capture-The-Flag
tasks.
These tasks will test your understanding and mastery of specific static and dynamic analysis methods and tools, the compilation process, assembly language - syntax, registers, memory handling, functions, - as well as your ability to identify and exploit simple buffer overflow vulnerabilities.
Return Oriented Programming
For the bonus exercise, you will have to use Return Oriented Programming (ROP).
This is a technique in which, if we have the ability to overwrite the return address, we execute gadgets
.
These gadgets
are simply portions of the existing code that end with a ret
instruction.
Examples of gadgets include:
pop rdi ; mov rdx, rax ; mov r12, rax ; jmp 0xd178
pop rdi ; pop rbp ; ret
pop rdi ; ret
pop rsi ; pop rdi ; jmp 0xbd5f
Notice that each gadget must end in a control-flow instruction, such as a ret
or a jmp
.
The reason is so that they can be chained together.
We usually write payloads that contain the addresses of these snippets.
Then we trigger the ROP attack by placing this payload to overwrite a code pointer with the first address in the payload (such as overwriting the return address with this address).
Follow the example below to get a better picture:
The image above aims to execute pop rdx; pop rbx; ret
.
Let's assume a function's return address is overwritten with that of the gadget, gadget_addr
.
The following things are going to happen:
The function's
ret
will be executed and therip
will move to the first instruction of the gadget:pop rdx
; thersp
will move towards the number 3 on the stack.pop rdx
is executed, so the number pointed byrsp
is popped intordx
, which is 3;rsp
increases and now points to 4.Similarly,
pop rbx
will pop the number 4 intorbx
; nowrsp
points to the new return address.The gadget's
ret
is executed, thus allowing us to execute new code: either a separate function, or a new gadget.
To determine the address of a gadget in a binary, there is the tool ROPgadget.
Alternatively, in pwndbg
, you can use a command like rop --grep "pop rsi"
.