overthewire - behemoth1

behemoth1 looks about the same as behemoth0, to start. in behemoth0, the program opens, asks the user for a password, compares the user inputted string to another string with strcmp. if they match, the user is granted a shell as behemoth1, and can then read /etc/behemoth_pass/behemoth1 for the next level's pasword.

in behemoth1, things are a bit different. The user is presented with a gets() prompt for a password, and then the door is seemingly closed shut in your face, as you are presented with a very final sounding

"Authentication failure.

No matter what you might input. If disassembled, you won't find any conditions you can influence that might change this. No j** instructions between user input and ret. This isn't the end of things though, because there's a vulnerability here. A bog-standard, butt-ass-naked buffer overflow. No stack protection. The good folks at intruded/overthewire set us up with gdb and PEDA, so let's put them to good use.

A few steps after inputting A x 124. The difference between the remaining 'A's and the amount we put in is our offset, which comes out to 79. After our input, but before we gain control of the program, a leave instruction occurs that changes the value of ESP to what was previously stored at EBP, and EBP to something on/near the top of the stack. We control where the ret points with the 4 bytes that come after the 79 junk bytes.

ESP points to the bytes after the end of the buffer now, so let's just stuff some NOPs and shellcode up in this shit after an address to one of those jmp esp; ret gadgets. This one is in libc, so there won't be any fuckery with differences in layout between GDB and normal execution. I used the one at 0xF7F7C6B7. Very painless. Normally I would just try to jump straight to an address somewhere in the NOPs before the shellcode, but this is much nicer.

The setup so far should look about like this.

perl -e 'print "A" x 79 . "\xB7\xC6\xF7\xF7" . "\x90" x 64 . whatever shellcode . "\x90" x 32;`

I encountered some difficulty here in two ways:
first was not being able to interact with the spawned shell at all. I solved this by using '-' with cat before piping it to the program. Like so:

cat ./myshit - | /behemoth/behemoth1

second was trying to use just normal execve(bin/sh) shellcode, which doesn't carry the euid with it, so a shell would spawn but as behemoth1 instead of behemoth2. I fixed this by finding some shellcode that called /bin/sh with the -p flag to preserve the euid, courtesy of one Mr. Jonathan Salwan.

With that out of the way, we can move on to the next level. Good fun.

disclaimer: this took me an embarrassing amount of time for someone who's done similar exercises before. I'm presenting this as if it were way easier for me than it was and with significant effort made to appear more competent than i am. this was a huge pain in the ass and i spent at least half a week on it.

the shellcode I used can be found here

<-prev (home) next->