非栈上fmt劫持
https://www.cnblogs.com/seyedog/p/17891490.html
原理分析
程序执行流程图:

函数最终exit退出时会调用fini_array函数,如果可以控制fini_array,就可以劫持程序流程
dl_fini函数
main->exit->__run_exit_handlers->dl_fini
dl_fini函数中会调用call rax

我们可以控制l_addr,浅紫色为残存下来的l_addr地址,我们可以利用fmt去修改这个数值,劫持程序返回到tar_addr
偏移计算:偏移=tar_addr-fini_arry_addr


例题
2023金盾杯的一道题
这里有close(1),没办法输出,这样我们偏移就不好找,同时开启沙盒,只有一次非栈上fmt
思路:直接用到fini_array劫持,通过修改dl_fini数组里的偏移值,使函数在退出时执行我们写在bss段上的shellcode


我们可以将close(1) 修掉,nop掉

完成:


保存

偏移计算
偏移=shellcode_addr-fini_addr
0x40406B - 0x403D98 = 723
修改的同时读入orw shellcode
1 | from pwn import* |
栈上fmt劫持
fmt直接修改
[CISCN 2019西南]
给出system函数,但只有一次fmt,64字节,修改printf.got-system.plt,fini_array-main

1 | from pwn import* |