目录

如何在二次释放前修改函数指针

修改函数指针流程

如何获得进程的加载基址

puts函数的调用

如何获取system函数地址

说一下用DlyELF函数

如何调用system函数

ROP需要的栈布局

read函数的妙用

参数”/bin/sh”如何传递过去

参考资料

官方提供的解法还是有一些意思的。对于我来说又多了一种见识。


如何在二次释放前修改函数指针

修改函数指针流程

分配2个0x4字节长度的字符串后内存布局

图1 分配2个0x4字节长度的字符串后内存布局

删除3次字符串后内存布局,3次,而不是3个

图2 删除3次字符串后内存布局

是删除3次,而不是删除3个字符串,str0被删除了两次,这就让str0有了一个回指str1的指针,再被分配出去之后,str1依然能够在fastbin中链接上str0的空间。

如何修改release指针

图3 如何修改release指针

让人惊讶的事情发生了,不是吗。由于多删除了一次str0,使得glibc以为fastbin队列里面有三个空闲块,它才不管这三个块是不是同一个呢,只要指针能引用就


如何获得进程的加载基址

puts函数的调用

  我们都知道,puts能够输出一个字符串到屏幕,那么如果我们能调用它,并传给它一个指针,它就会认为这个指针指向一个字符串,然后打印给我们看。如果我们给的这个指针指向的地址包含了一个函数地址,那么我们自然能获得函数地址了啊。

  作者是如何做的呢?

  调用puts的方法就是修改release指针,用str1的数据形式将release_ptr最低字节修改为0x2d。为什么只修改最低一个字节就可以了呢?我们看原始函数的地址和调用puts的指令地址就知道了。

图4 原始释放函数的地址

图5 调用puts的指令地址

  可以看到,两个地址只有最低一个字节不同。

  然后,我们就delee(0)可以看到puts把str0打印出来了,将release_ptr的值当做字符串打印出来了。

  然后减掉0xd2d,就可以得到进程的加载基址了。


如何获取system函数地址

  作为分析来说直接用本地libc库来定位比较方便,目前与上篇文章一样。

  说一下用DlyELF函数。

  DlyELF是pwn库提供的一个函数,用来定位库函数在进程内的地址。

  那么如何使用呢?

    1.  首先我们要提供一个leak(addr)函数,这个函数要能够实现:

      1)  能够读取addr处至少一个字节数据

      2)  能够多次调用不至于崩溃

    2.  要将程序中的信息传递给DlyELF

    3.  使用方式:

      DynELF(leak_addr, elf=ELF('./fheap'))

    4.  leak_addr函数的实现:

#参考FlappyPig的做法,结合官方提供脚本中的函数
def leak(leak_addr):
create(4, '\x00')
index0 = 9
#addr是进程基址
printf_plt = 0x9d0 + addr
#print "printf_plt:", hex(printf_plt)
payload = ""
payload += ("%%%d$s--..--"%(index0)).ljust(0x18, 'a')
payload += l64(printf_plt)[:3] + "\x00"
create(0x20, payload)
target.recvuntil('quit')
target.sendline('delete ')
target.recvuntil('id:')
target.sendline('')
target.recvuntil('sure?:') padding = "yes.aaaa"
padding += l64(leak_addr)
target.sendline(padding) data = target.recvuntil('--..--')[:-6]
data += "\x00"
delete(1)
return data

如何调用system函数

  先delete(1),然fastbin回到图2状态。以便我们修改函数指针。

  这次作者要调用0x11dc处的指令,我们来看看,这个地址的指令能做什么事。

图6 0x11DC处地址的指令

  加上ret_addr,一个5个参数,为什么要弹5个参数呢?

  我们想一想,当修改release_ptr直接调用0x11DC偏移处的指令时候,rbp和rsp并没有回复到进函数时候的初始值。初始值是怎么样的呢?

图7 delete_string函数的初始栈布局

  rsp指向偏移120,buf指向偏移110,在删除字符串进行确认时候,输入的字符串前八个字节是”yes aaaa”,再加上调用release_ptr用的是call方式压栈一个,正好会弹出4个参数,然后”yes aaaa”之后的值会被当做ret_addr给rip。

  那么作者下一步调用的是哪个函数呢?

  来看看作者构造的ROP需要的栈布局。

ROP需要的栈布局

图8 ROP链的构造

    rip从0到6依次执行

read函数的妙用

    参考图8,read将system读入到atoi的got表项,而这个表项随后会被调用。起始就调用了我们写入的system地址

参数”/bin/sh”如何传递过去

  参考图8,“/bin/sh”这个参数如何传递过去呢?作者调用了getint函数,这个函数是做什么的呢?将字符创转化成数字。

  对于我们而言,这个函数有什么用呢?它会读入“/bin/sh”保存到一个地方,然后传递给atoi函数。


运行结果

图9 运行结果


总结

  作者调用system的方式真是让我这个新手大开眼界,回味无穷。

  而且构造能覆盖release_ptr的fastbin队列的手法也让我惊叹。

  收获颇多。


参考资料

  [1]  Hctf官方解题说明:

http://www.freebuf.com/articles/web/121778.html

hctf2016 fheap学习(FreeBuf发表的官方解法)的更多相关文章

  1. hctf2016 fheap学习(FlappyPig队伍的解法)

    目录 漏洞原理 二次释放 如何在第二次释放前修改函数地址 fastbin的特性 修改函数指针流程 如何获得进程的加载基址 格式化字符串漏洞 确定printf函数在代码段中偏移 printf函数输出想要 ...

  2. 深度学习框架: Keras官方中文版文档正式发布

    今年 1 月 12 日,Keras 作者 François Chollet‏ 在推特上表示因为中文读者的广泛关注,他已经在 GitHub 上展开了一个 Keras 中文文档项目.而昨日,Françoi ...

  3. MVP学习笔记——参考Google官方demo

    demo地址:https://github.com/googlesamples/android-architecture 在这个项目里,每个包的分工都很明确,大体上来说,一个包会对应一个界面.一个界面 ...

  4. [C#学习]0.发表之前想说的

    在这里我将学习C#编程,首先我也只是一个初学者,只是为了以后的学习,并且方便复习,所以决定在这里记录总结一些知识,简单的写一个教程.所以在这里或许难免有一些错误,欢迎大家指出,一起进步. 在这里我使用 ...

  5. UE4的AI学习(2)——官方案例实例分析

    官方给出的AI实例是实现一个跟随着玩家跑的AI,当玩家没有在AI视野里时,它会继续跑到最后看到玩家的地点,等待几秒后如果仍然看不到玩家,则跑回初始地点.官方的案例已经讲得比较详细,对于一些具体的函数调 ...

  6. deno学习四 docker 运行官方的一个http file server

    github 上已经有人搞了一个deno 的docker 镜像,是基于源码编译的,挺好的 所以结合官方的http server demo 使用docker 运行 环境准备 docker-compose ...

  7. ICE学习笔记一----运行官方的java版demo程序

    建议新手和我一样,从官网下载英文文档,开个有道词典,慢慢啃. 官方文档下载: http://download.csdn.net/detail/xiong_mao_1/6300631 程序代码就不说了, ...

  8. 同时安装Python2,Python3如何解决冲突问题【官方解法】

    使用py -2或py -3命令来区分调用Python启动器 去掉参数 -2/-3如何运行? 每次运行都要加入参数-2/-3还是比较麻烦,所以py.exe这个启动器允许你在代码中加入说明,表明这个文件应 ...

  9. 微信小程序入门——怎么建多个项目?(导入官方Demo程序进行学习)

    昨天1月9日微信小程序发布,顿时被朋友圈刷爆,今天看了一下官方文档,自己开始一步一步搭建环境体验小程序开发. 常见问题: 1.微信小程序开发是否需要重新创建开发者账号? 需要,即使之前申请了微信服务号 ...

随机推荐

  1. 【BIEE】16_饼图应用

    在BIEE中,我们可以使用饼图来展示报表数据 饼图在使用中有三元素:①切片 ②饼图 ③度量 那么我们来分别看下这三个元素的功能分别是什么? 我们通过上图可以看出度量中存在2个度量,那么此时的饼图数量是 ...

  2. Android设置拍照或者上传本地图片

    效果例如以下: 看代码: MainActivity类中: package com.example.ceshidemo; import java.io.ByteArrayOutputStream; im ...

  3. Jmeter-安装及配置(一)

    Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动态资源,例如静态文 ...

  4. dedecms上传图片相对路径改成绝对路径方法

    很多朋友使用dedecms的时候都用了二级域名的功能,所以造成很多文章中图片不显示的问题. 解决方案如下: 1. 进入dede后台"系统"-"系统基本参数"-& ...

  5. nginx location 或操作

    location ~* (\.(7z|bat|bak|ini|log|rar|sql|swp|tar|zip|gz|git|asp|svn)|/phpmyadmin) { deny all; }

  6. nginx中ngx_list的数据结构

    今天没事了,在查看nginx源代码中看到ngx_list的结构,发现设计为链表数组的形式,不知道为什么这样设计 struct ngx_list_part_s { void *elts;//指向数组的起 ...

  7. Oracle 数据库的连接

    仿照http://blog.csdn.net/makenothing/article/details/17080069 1 建立Oracle连接 VS2010中加入数据库连接 得到连接字符串 Data ...

  8. MII、GMII、RMII、SGMII、XGMII

    MII即媒体独立接口,也叫介质无关接口.它是IEEE-802.3定义的以太网行业标准.它包括一个数据接口,以及一个MAC和PHY之间的管理接口(图1). 数据接口包括分别用于发送器和接收器的两条独立信 ...

  9. YUYV格式到RGB格式的转换

    为什么YUYV格式要转到RGB格式,视频的显示调用的多数API都是基于RGB格式,所以需要进行格式的转换. YUYV格式如下: Y0U0Y1V0 Y2U1Y3V1.......... 说明:一个Y代表 ...

  10. python模块学习之json

    更多信息请参考官网地址: https://docs.python.org/3.6/library/json.html 19.2. json - JSON编码器和解码器 Source code: Lib ...