目录

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

修改函数指针流程

如何获得进程的加载基址

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. java中string和int互相转化 (转)

    1 如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([ ...

  2. (五)EasyUI使用——datagrid数据表格

    DataGrid以表格形式展示数据,并提供了丰富的选择.排序.分组和编辑数据的功能支持.DataGrid的设计用于缩短开发时间,并且使开发人员不需要具备特定的知识.它是轻量级的且功能丰富.单元格合并. ...

  3. java类反射

    http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

  4. oc block 遍历数组及字典

    原遍历数组NSArray * lines = ...for (NSString * line in lines) { // ...}for (int i = 0; i < lines.count ...

  5. http://www.allegro-skill.com/thread-2506-1-1.html

    http://www.allegro-skill.com/thread-2506-1-1.html

  6. Codeforces Round #240 (Div. 1)B---Mashmokh and ACM(水dp)

    Mashmokh's boss, Bimokh, didn't like Mashmokh. So he fired him. Mashmokh decided to go to university ...

  7. Atitit eclipse新特性总结3.1---4.4  4.5

    Atititeclipse新特性总结3.1---4.4  4.5 1. Eclipse 4.4 Luna正式发布了.1 1.1. 新版本的Eclipse默认对Java8提供支持1 1.2. 内存分析器 ...

  8. Backup and Recovery Basics1

    一.Backup and Recovery Overview 1.Backup and Recovery Overview 1.1 What is Backup and Recovery? 一般,备份 ...

  9. 实现html锚点的两种方式

    1,a标签+name属性. 2,使用标签的id属性:

  10. Visual Studio 调试小技巧-从查看窗口得到更多信息(转)

    原文地址:http://blog.csdn.net/cadcisdhht/article/details/5651488