Binary Exploitation

Name
Solves

Berbuka Dengan PIE πŸ₯‡

9

Perfect πŸ₯‡

5

About You πŸ₯‡

2

u-turn πŸ₯‡

1

Berbuka Dengan PIE

Description

Author: ilupii

Aku dan temanku bingung mau berbuka pake apa, tapi tiba tiba ada orang bagi bagi takjil kue pie

Connect: nc playground.tcp1p.team 19001

Initial Analysis

We are given files:

β”Œβ”€[mirai@parrot]─[~/ctf/TCP1P Ramadhan 2025/Berbuka Dengan PIE]
└──╼ $tree .
.
β”œβ”€β”€ chall
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Dockerfile
└── flag.txt

We do basic security checks on the file:

Code Analysis

We open the chall file in IDA:

In here, when we chose the option 2, it will print out the main() address function. Since our binary is PIE enabled, this defeats the PIE enabled protection.

There is also a bug in vuln() function:

An obvious buffer overflow, fgets is taking in 100 characters into buffer s[32].

Since there's is no win function, we will need to do ret2libc.

Exploitation

This one is straightforward, we will just need to calculate the offset from the main() function to the base address. The problem is when we are trying to leak libc. There is no easy way to put a libc address into RDI register since there are no pop rdi; ret; gadgets.

But when we see on debugger, when returning from the vuln() function, the RDI registers is actually populated with funlockfile address. With this knowledge, we can just call puts, calculate the offset from libc.sym['funlockfile'] to get the libc base address and then back to vuln to do a second buffer overflow.

Leaking libc

With our leaked libc base address, now we can use the function inside of libc. We can call system("/bin/sh") to get a shell and read the flag.

Exploit ran against the remote server

Perfect

Description

Author: ilupii

i have faith what i see, now i know i have met an angel in person and she looks perfect.... perfect kayak binarynya

Connect: nc playground.tcp1p.team 4156

Initial Analysis

We are given files:

We do basic security checks on the file:

Code Analysis

There is a function called perfect():

Though there are no buffer overflow, this function is vulnerable to format string vulnerability, on line 10 and 13. With format string vulnerability, we can do arbitrary read and arbitrary write. We are given two format string. So my instant thought is first to leak saved RIP of the current stack and also leak libc address, then on the second format string, we can write a one gadget.

I didn't realize there was a win function here lol

Exploitation

We found that the stack address and libc address lives at offset %1$p and %67$p . We then calculate the stack address offset to current stack RIP and calculate libc base address.

We get that the offset from saved RIP to current leak is stack_leak + 0x8

With these leaks in our hand, we can overwrite at any address using the second format string vulnerability. Thankfully, pwntools have the automation just to do that.

Here i dumped one gadget using this tool:

When we send the payload, the return address will look like this:

Our saved RIP is overwritten with a one gadget

And we just continue execution and we will pop a shell.

Exploit being ran against the remote server

About You

Description

Author: ilupii

Do you think I have forgotten?

Connection: nc playground.tcp1p.team 19121

Initial Analysis

We are given files:

We do basic security check:

Tried to run it:

Code Analysis

There are several functions:

Here we see that there is a function called siapa() and mw() .

We can see that there's a format string vulnerability at line 13. But first we need to see the get_rand() function first:

This code essentially sets up a seed using the current time, then generate a random number, then essentially taking only the lowest 8 bits of the rand() value. Equivalent with v0 & 0xff

Then there is xor_encrypt(s, rand):

This function basically xor'ing every character in the string with the value from rand.

Knowing that:

AβŠ•B=CandAβŠ•C=BandBβŠ•C=AA \oplus B = C \\ and \\ A \oplus C = B \\ and \\ B \oplus C = A

We can XOR our chosen payload with the rand on server, and in the server, it will XOR it again, making it decrypted and reflect our actual payload. But in this case we want to use the format string, so we chose our payload so that it can leak addresses and stack canaries.

Then we go to the mw() function:

There's an obvious buffer overflow, fgets is taking 256 character into a buffer s[72]

Exploitation

So the idea is:

  1. Leak addresses and canaries via format string, but first we need to XOR our payload with the random value

  2. Do ret2libc

It took some amount of tries, because of latency issue

Exploit being ran against the remote server

u-turn

Description

Author: nouxia

turn 360 degrees and walk away

Connect: nc playground.tcp1p.team 33132

Initial Analysis

We are given files:

We do basic security checks:

Code Analysis

There's a single function called vuln():

At first glance, this code didn't seem vulnerable to anything. But knowing that scanf appends null byte at the end of input. This code is instantly vulnerable to an off-by-one null byte overflow.

Exploitation

Finding the Offset

At first, i tried to fuzz this to find the offset where i start to overflow the buffer.

Fuzz 1
Fuzz 2

The offsets when we overwrite RIP is always different.

At this point, i am clueless, so i tried asking my friend Hygge, he said "why not just use ret slep", so i did just that.

With that knowledge in mind, i changed my payload to this:

We got consistency!

Leaking libc

To leak libc, we can take a look the register state before it returns from vuln:

RDI points to libc.sym['funlockfile'] address, now we already have libc address in RDI, we will just need to call printf to get the leak.

Getting back to vuln

We will try to go back to vuln to get a second overflow. But, when we try to go back to vuln like this:

We are greeted with this error:

RSP not aligned to 16 bytes

To counter this error, we can do a technique called ret2start. This will restart the binary. Restoring the stack state just like when we first executed the binary.

Now we do the same thing with the second overflow, but with the target execve("/bin/sh", 0, 0) because system("/bin/sh") always throws an error:

We try to exploit this against the remote server we will got the flag:

Exploit being ran against the remote server

Last updated