BSidesSF CTF

Team: HCS

Rank: 14 / 583

Challenge
Category
Points
Solves

Can't Give In

Binary Exploitation

494 pts

31

Can't Give In (secure)

Binary Exploitation, Web Exploitation

775 pts

21

Can't Give In

Description

Can you get a shell?

Note: the binary should have an executable stack and minimal hardening, the goal is RCE

Author: ron

http://cant-give-in-4130d4ca.challenges.bsidessf.net:8080

Analysis

unlike the usual PWN challenges, instead of giving a connection string through tcp or netcat, we're given a link to HTTP.

visiting the website, it seems to be a static one as shown below

presented with a password form, I tried to submit it with a gibberish input, and got the response as shown below

we can see what is being sent through by capturing the request in BurpSuite

on the CTF platform, they gave us a binary called auth.cgi which seems to be what is handling our input indicated by the endpoint of our request, let's see what it is

it's missing every security mechanism (I have no idea why it says there's canary, but there's actually none), the binary itself is very simple with only a main function

the vulnerability lies quite clear as the length of read() is within our control and can be used to overflow the stack.

I've interacted with this kind of challenge before where the binary exploitation is through the HTTP medium in Tenable CTF 2023, I will use roughly the same script to setup my local debugging environment.

in short we can with pwntools, we can provide an additional environment variables upon summoning the process binary as follows:

this will be handy since the binary is taking the read size through the process environment variables.

otherwise if we wish to send the payload to the remote server, we can use python's requests library, and the CONTENT_LENGTH will be automatically handled for us.

Exploitation

to gain RCE the usual system("/bin/sh") or execve("/bin/sh", NULL, NULL) won't work. we don't establish a two way persistent communication using socks or other way.

Not to say though I'm not sure on this, there might be a change that our input is handled by a different application and forwarded to the actual challenge binary, spawning a shell would just mean spawning it in the server's local process with no actual communication is happening to us.

so the goal is to execute a Reverse Shell which is different and can be visualized with the picture below

there's many reverse shell payload out there, but since we're able to execute shellcode with no restriction, I just took one from the link below

next is to find a gadget that would execute our shellcode within the stack, since the binary is statically compiled, we have tons of options though one that crossed my first though: jmp rsp is not to be found.

however we do have call rsp which in practice, does the same thing

next, we need for our machine to listen for connection and send the shellcode against the remote server

Below is the full exploit script:


Can't Give In (secure)

Description

Can you get a shell?

Note: this is similar to cant-give-in, but the stack is no longer executable

Flag is located in: /home/ctf/flag.txt

Author: ron

http://cant-give-in-secure-05060d6d.challenges.bsidessf.net:8080

Binary Analysis

the binary and overall environment is the same as the previous challenge, however one thing different is that this time the binary has NX enabled

Exploitation

the idea is still the same, however the execution is different, instead of shellcoding, we will ROP instead.

what the above shellcode does is equivalent to the following command in linux terminal:

the port used by the shellcode I linked above uses 1337 while what I used in this challenge is 9001

this would quite be trivial or easy to do if we have system() as we just pass the string to it. However the static binary doesn't have that symbol. Instead we have to manually craft it into execve()

according to the manual execve() takes 3 parameters

I would however, retype it as execve(char *, char *[], char *[]) to make it more intuitive as it is a pointer to an array containing the parameters or environment variables you wish to pass to the executable.

which means to execute the reverse shell payload, we would need to prepare our arguments such that when calling it would be:

for this, we would need a writeable address, since the binary has no PIE, I decided to use the .bss section to write our arguments.

to write we will use this gadget with rsi as where to write and rdx as what to write:

and to control those values we have these popsicles:

since we'll we writing a lot values, I've write this function to simplify things

first, lets write the strings into the binary

next, we will create an array that will contain form the arguments and contains a pointer to one of the strings above

so, our argv is at the address of BSS + 48

then we'll just have to set the parameters into execve()

all correct and set, launch it against the remote server

Below is the full exploit script:

Last updated