Hello, I'm 9x14S and I participated on this CTF as a member of team 0xE0F.
uoftctf{libc_is_abundant_of_gadgets}
uoftctf{arbitrary_machine_code_execution}
uoftctf{patched_the_wrong_function}
uoftctf{you_can_always_return}
UofTCTF{BOD_Iberia_A340-300}
uoftctf{allUsers_is_not_safe}
uoftctf{s3rv1c3_4cc0un75_c4n_83_un54f3}
uoftctf{you_got_out_of_jail_free}
uoftctf{b4by_j4v4scr1p7_gr3w_up_4nd_b3c4m3_4_h4ck3r}
uoftctf{x0r_iz_r3v3rs1bl3_w17h_kn0wn_p141n73x7}
uoftctf{AT1d2jMCVs03xxalViU9zTyiiV1INNJY}
uoftctf{fired_for_leaking_secrets_in_a_pdf}
uoftctf{d0cx_f1l35_c4n_run_c0de_t000}
uoftctf{Y0UR Pitch IS 70O H!9H}
{i_understand_the_mission}
{FCC_ID_Recon}
{Processor_Recon}
{Xor!=Encryption}
This challenge provides a binary called buffer-overflow
, with the following checksec
output:
Running it gives no output, only waits for user input. Like most challenges like this, they just focus on the exploitation so I immediately threw it into gdb and inputted a cyclic pattern of length 200.
This output means that the buffer size is 64 bytes, plus 8 bytes from the extra overwritten stored RBP.
So let's look for somewhere interesting to jump to. I ran rabin2 -s buffer-overflow
to get the symbols (functions) in the binary:
The shell
function seems interesting, so I disassembled with objdump -d buffer-overflow | grep shell -C 10
:
This basically means that this function spawns a shell, so let's jump to it! I grabbed the address of the function (0x0000000000401136
), and started writing the Python script:
The script is just an automated way to send some padding plus the packed (converted to bytes) address.
After running it, I got the shell and the flag:
Flag: uoftctf{reading_manuals_is_very_fun}
This challenge provides a binary called babyshellcode
with the following checksec
output:
Seeing the name and the output, this means that we have to overflow the stack with some shellcode, and then jump to it.
Again with rabin2 -s babyshellcode
we get the functions:
This time, this output is slightly weird, but this only means that the binary was (probably) hand-crafted.
Let's get the disassembled function _start
with objdump
:
The most interesting part of this is the last instruction jmp *%rsp
which means we jump into the stack! So basically this is the entrypoint to which we can run the shellcode.
I'll save the GDB output this time, as this binary didn't have any buffer.
Let's get some shellcode! At first, I tried using pwntools' shellcraft, but for some reason it didn't work, so I ended up just opting for msfvenom
instead:
The way I solved it was just by running cat f - | ./babyshellcode
(important to also cat -
, to not break the pipe and keep typing), and this gave a shell:
So the actual exploit was to pipe the shellcode to the remote connection and get the flag:
Flag: uoftctf{arbitrary_machine_code_execution}
This challenge provides a binary called patched
with this checksec output:
Nothing interesting in the output, and running it just tries to get some input, so I tried with rabin2 -s patched
and saw that there was another shell
function.
I immediately tried to overflow the return address to jump to that function (the buffer size is the same as the first challenge) by using this script:
Which opened a shell and gave me the flag:
Flag: uoftctf{patched_the_wrong_function}
(Opinion: this challenge sucked, it was basically copying and pasting the first exploit script)
This one was slightly harder than the first three, but easy enough as it is a basic ROP (return oriented programming) challenge.
Provided files: nothing-to-return
, libc.so.6
, ld-linux-x86-64.so.2
.
checksec
output:
Here, the interesting part is the runpath
part, which means that the binary uses a libc
in the same directory. This can't be any more obvious that it is a return-to-libc challenge.
For some reason, running the binary in my machine resulted in error each time, so I had to solve it fully remotely.
It prints the address of printf
, so that's basically a libc leak from which we can calculate the address of libc when linking occurs. I used a regular expression to parse it in the script.
The relative address of printf
is 0x00056250
, so the script has to receive to the binary output, get the leaked printf
address, convert it to int
and then subtract the relative address from it, to get the libc base.
After that, we have to get a few other parts:
/bin/sh
string.system
(or execve
)pop rdi; ret
gadgetret
gadget (to avoid the movaps
error that requires stack alignment when jumping to libc functions)The /bin/sh
string can be found inside libc, by running strings -t x libc.so.6 | grep /bin/sh
:
The system
function address can be found like printf
was found. This is the address: 0x0004f760
The ret
gadget can be found in the binary itself (to avoid having to calculate its address from libc), but the pop rdi
gadget has to be found in libc. The addresses are: 0x000000000040101a
and 0x0000000000028265
(libc), respectively.
Now the only part left is joining all of this into the solve script, overflowing the buffer and writing the ROP chain into the stack, to then jump into it.
Script:
Output:
Flag: uoftctf{you_can_always_return}
This challenge provides a link to the website (https://storage.googleapis.com/out-of-the-bucket/src/index.html
), at which we can see a two flags and some irrelevant text.
The first thing I tried to do, was to climb the directory tree upward, by requesting the src/
directory, but that didn't give me any interesting response.
Next, I tried requesting the out-of-the-bucket
directory, and got this XML response:
In this response, we can see a new endpoint: (/secret/
), along with two files contained in that directory:
dont_show
funny.json
Requesting the /secret/dont_show
file downloads it, and cat
ing it gives us the flag:
(The funny.json
file is for the next challenge)
Flag: uoftctf{allUsers_is_not_safe}
This challenge provides a PDF file named secret.pdf
.
Opening it in a PDF reader (here I'm using okular
) shows this:
The flag is under the blackened rectangle, but the PDF is DRM protected, which means we can't copy it:
Thankfully, okular
has an option to ignore DRM protection, which after disabling, I just went and copied the flag.
Flag: uoftctf{fired_for_leaking_secrets_in_a_pdf}
WIP