Bo1lers CTF: Jumpdrive Write
Hey everyone, welcome to my write-up for the PWN challenge: Jumpdrive from the b01lers CTF! This is my first ever write-up, and my first timed CTF on a team. It was a ton of fun, and I learned a whole lot from this experience even though I personally only solved one challenge.Starting Out
Looking at the challenge we are given a host and a port to connect to as well as a link to download the binary.
I’m first going to connect with nc to test what the program is doing.
Looking at that we can see the program is just printing back our input. Hmm okay, we can work with that. Let’s download the binary, and gather some info on it.
Binary Examination
Once the binary is downloaded I'm going to run strings on it for some basic info, and if we're lucky we can grab the flag that way.
We get a good bit of detail out of this!
- We see fopen and flag.txt. I think it’s safe to assume the binary will open the flag file, and store the contents somewhere in memory. Perfect!
- Aha, there it is, printf. There are definitely some vulnerabilities in printf if we aren’t careful, which I’ll discuss a little bit later.
- We see __stack_chk_fail. Being a noob it took me a bit of research to get this one. We have a stack canary, so that means we can’t overflow this binary. If you’re like I was, and had no clue what a stack canary was you can read about it here: Stack Canary
Let’s try to run the file locally. Since there is a stack canary we’ll see if we can work with a format string vuln. We’ll first need to create a dummy flag.txt file in the same folder as the jumpdrive binary since it is reading the file. We’ll then run the program, and try see if there is a format string vuln in printf.
Lookie there, it’s vulnerable! We successfully read from the stack! But wait, why does this work? Well there’s a safe way, and an unsafe way to use printf let’s take a look at both of them below.
- Safe way ->
printf("This is my string: %s", myString)
- Unsafe way ->
printf(myString)
As for the why, I’ll let someone far more knowledgeable than me explain it: Printf Vuln
This is all great news, but how do we actually use any of this information to exploit this program. Stay tuned for the next paragraph to see.
Exploitation
Let's test our local binary once more, but this time let's read as much of the stack as we can. Tip: One thing we do know from the CTF organizer's is that ASLR is enabled for all PWN challenges.
From an initial look we can see that there seems to be 3 addresses that hold the same data each time (highlighted in previous image). We can also see our input at the end of the output! Keep in mind we are looking at Little Endian ordering, so when we look at the end of the output we can see that 0x252e702541414141
is actually 4141414125702e25
which corresponds with the beginning of our intput: AAAA%p.%
. Let’s run gdb, and take a look at what’s going on.
At main + 112
we see the call to fopen, at main + 144
we see 0xdeadbeef that we saw when reading from memory, and at main + 294
we see a call to printf. If we set a break point at printf break *main + 294
and then run the program we can view some info. I’m using gdb peda to enhance the display of gdb, and because I like the output. Let’s take a look at the stack.
Awesome! We see the three common outputs we saw from printing memory, and right after that we see our flag! So, if we’re correct we should be able to read the flag from the memory address’ directly following 0x400911d14e3bcd36
! Let’s check it out locally.
So, considering Little Endianess, if we hex to ascii the two memory blocks following known output we get our flag! 5468697369736d79 74657374666c6167 == Thisismytestflag
! We got it! Let’s run this on the server, and see if we get the flag there!
Now if we take the 3 memory blocks + the beginning of the fourth we get the flag for the challenge!
706374667b707231 6e54665f317a5f34 5f537434525f6d34 707d == pctf{pr1nTf_1z_4_St4R_m4p}
. Challenge pwned!